程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++調用外部應用程序的方法的整理總結

C++調用外部應用程序的方法的整理總結

編輯:C++入門知識

 一、三個SDK函數:

WinExec,ShellExecute ,CreateProcess可以實現調用其他程序的要求,其中以WinExec最為簡單,ShellExecute比WinExec靈活一些,CreateProcess最為復雜。
WinExec 兩個參數,前一個指定路徑,後一個指定顯示方式。
ShellExecute 可以指定工作目錄,並且還可以尋找文件的關聯直接打開不用加載與文件關聯的應用程序,ShellExecute還可以打開網頁,啟動相應的郵件關聯發送郵件等等。
CreateProcess 一共有十個參數,不過大部分都可以用NULL代替,它可以指定進程的安全屬性,繼承信息,類的優先級等等。如果我們要得到足夠多的關於新的進程的信息,控制新的進程的細節屬性,若要達到這些目的,我們就需要使用CreateProcess函數了。

1.winexec(String lpCmdLine,Long nCmdShow);

參數說明:

 


參數 類型及說明 lpCmdLine String,包含要執行的命令行  
nCmdShow Long,為窗口指定可視性方面的一個命令。請用下述任何一個常數 SW_HIDE 隱藏窗口,活動狀態給令一個窗口 SW_MINIMIZE 最小化窗口,活動狀態給令一個窗口 SW_RESTORE 用原來的大小和位置顯示一個窗口,同時令其進入活動狀態 SW_SHOW 用當前的大小和位置顯示一個窗口,同時令其進入活動狀態 SW_SHOWMAXIMIZED 最大化窗口,並將其激活 SW_SHOWMINIMIZED 最小化窗口,並將其激活 SW_SHOWMINNOACTIVE 最小化一個窗口,同時不改變活動窗口 SW_SHOWNA 用當前的大小和位置顯示一個窗口,不改變活動窗口 SW_SHOWNOACTIVATE 用最近的大小和位置顯示一個窗口,同時不改變活動窗口 SW_SHOWNORMAL 與SW_RESTORE相同  


例: winexec("c:\\a.txt",SW_SHOW);

2.ShellExecute


 

參數 類型及說明 hwnd Long,指定一個窗口的句柄,有時候,windows程序有必要在創建自己的主窗口前顯示一個消息框 lpOperation String,指定字串“open”來打開lpFlie文檔,或指定“Print”來打印它 lpFile String,想用關聯程序打印或打開一個程序名或文件名 lpParameters String,如lpszFlie是可執行文件,則這個字串包含傳遞給執行程序的參數 lpDirectory String,想使用的完整路徑 nShowCmd Long,定義了如何顯示啟動程序的常數值。參考上表.  

使用方法如下:
例:ShellExecute(Handle, ''open'', PChar(''c:\test\readme.txt''), nil, nil, SW_SHOW);
ShellExecute(NULL,"open","C://Test.txt",NULL,NULL,SW_SHOWNORMAL); // 打開C:/Test.txt 文件
ShellExecute(NULL, "open", "http://www.BkJia.com",/ NULL, NULL, SW_SHOWNORMAL); // 打開網頁www.2cto.com
ShellExecute(NULL,"explore", "D://C++",NULL,NULL,SW_SHOWNORMAL); // 打開目錄D:/C++
ShellExecute(NULL,"print","C://Test.txt",NULL,NULL, SW_HIDE); // 打印文件C:/Test.txt

3.CreateProcess



 參數類型及說明lpApplicationNameString,要執行的應用程序的名字。可設為vbNullString;在這種情況下,應用程序的名字應在lpCommandLine參數的起始處出現lpCommandLineString,要執行的命令行。可用GetCommandLine函數取得一個進程使用的命令行。Windows會盡可能地根據下述搜索順序來查找執行文件:
(1)包含了父進程執行文件的目錄
(2)父進程當前的目錄
(3)由GetSystemDirectory返回的系統目錄
(4)僅適於windows NT:16位系統目錄
(5)由GetWindowDirectory返回的Windows目錄
(6)由PATH環境變量指定的目錄lpProcessAttributesSECURITY_ATTRIBUTES,指定一個SECURITY_ATTRIBUTES結構,或傳遞零值(將參數聲明為ByVal As Long,並傳遞零值)——表示采用不允許繼承的默認描述符。該參數定義了進程的安全特性lpThreadAttributesSECURITY_ATTRIBUTES,指定一個SECURITY_ATTRIBUTES結構,或傳遞零值(將參數聲明為ByVal As Long,並傳遞零值)——表示采用不允許繼承的默認描述符。該參數定義了進程之主線程的安全特性bInheritHandlesLong,TRUE表示允許當前進程中的所有句柄都由新建的子進程繼承dwCreationFlagsLong,來自API32.TXT文件的一個或多個下述常數之一,它們都帶有前綴CREATE_。下面這些用於VB程序員:CREATE_SEPARATE_WOW_VDM(僅適用於NT)啟動一個16位的Windows應用程序時,強迫它在自己的內存空間運行CREATE_SHARED_WOW_VDM(僅適用於NT)啟動一個16位的Windows應用程序時,強迫它在共享的16位虛擬機(VM)內運行CREATE_SUSPENDED立即掛起新進程。除非調用了ResumeThread函數函數,否則它不會恢復運行也可能是下述常數之一,用於指定優先級IDLE_PRIORITY_CLASS新進程應該有非常低的優先級——只有在系統空閒的時候才能運行。基本值是4HIGH_PRIORITY_CLASS新進程有非常高的優先級,它優先於大多數應用程序。基本值是13。注意盡量避免采用這個優先級NORMAL_PRIORITY_CLASS標准優先級。如進程位於前台,則基本值是9;如在後台,則優先值是7不要在VB中使用REALTIME_PRIORITY_CLASSlpEnvironmentAny,指向一個環境塊的指針(環境緩沖區的頭一個字符,或者環境塊的地址)lpCurrentDriectoryString,新進程的當前目錄路徑。調用函數的時候,可用vbNullString指定當前目錄lpStartupInfoSTARTUPINFO,指定一個STARTUPINFO結構,其中包含了創建進程時使用的附加信息lpProcessInformation
PROCESS_INFORMATION,該結構用於容納新進程的進程和線程標識符。大多數情況下,一旦這個函數返回,父應用程序都會關閉兩個句柄。
 

二、WinExec、ShellExecute和CreateProcess及返回值判斷方式

有三個API函數可以運行可執行文件WinExec、ShellExecute和CreateProcess。CreateProcess因為使用復雜,比較少用。
  WinExec主要運行EXE文件。
  ⑴ 函數原型: UINT Win Exec(LPCSTR lpCmdLine, UINT uCmdShow);
  ⑵ 參數:
  lpCmdLine:指向一個空結束的字符串,串中包含將要執行的應用程序的命令行(文件名加上可選參數)。
  uCmdShow:定義Windows應用程序的窗口如何顯示,並為CreateProcess函數提供STARTUPINFO參數的wShowWindow成員的值。
  ⑶ 返回值:
  若函數調用成功,則返回值大於31。若函數調用失敗,則返回值為下列之一:
  ① 0:系統內存或資源已耗盡。
  ② ERROR_BAD_FORMAT:EXE文件無效(非Win32.EXE或.EXE影像錯誤)。
  ③ ERROR_FILE_NOT_FOUND:指定的文件未找到。
  ④ ERROR_PATH_NOT_FOUND:指定的路徑未找到。
  雖然Microsoft認為WinExec已過時,但是在許多時候,簡單的WinExec函數仍是運行新程序的最好方式。簡單地傳送作為第一個參數的 命令行,還需要決定如何顯示程序(該程序也許會忽視它)的第二個參數。通常,將其設置為SW_SHOW,也可嘗試SW_MINIMIZED或 SW_MAXIMIZED。WinExec不允許用CreateProcess獲得的所有選項,而它的確簡單。

  ShellExecute不僅可以運行EXE文件,也可以運行已經關聯的文件。
1、標准用法
  ShellExecute函數原型及參數含義如下:
HINSTANCE ShellExecute(HWND hwnd, LPCTSTR lpOperation, LPCTSTR lpFile, LPCTSTR lpParameters, LPCTSTR lpDirectory, INT nShowCmd);
  ●hWnd:用於指定父窗口句柄。當函數調用過程出現錯誤時,它將作為Windows消息窗口的父窗口。例如,可以將其設置為應用程序主窗口句柄,即Application.Handle,也可以將其設置為桌面窗口句柄(用GetDesktopWindow函數獲得)。
  ●lpOperation:用於指定要進行的操作。其中“open”操作表示執行由FileName參數指定的程序,或打開由FileName參數指定的文件或文件夾;“print”操作表示打印由FileName參數指定的文件;“explore”操作表示浏覽由FileName參數指定的文件夾。當參數設為nil時,表示執行默認操作“open”。
  ●lpFileName:用於指定要打開的文件名、要執行的程序文件名或要浏覽的文件夾名。
  ●lpParameters:若FileName參數是一個可執行程序,則此參數指定命令行參數,否則此參數應為nil或PChar(0)。
  ●lpDirectory:用於指定默認目錄。
  ●lpShowCmd:若FileName參數是一個可執行程序,則此參數指定程序窗口的初始顯示方式,否則此參數應設置為0。
  返回值:
[cpp]
#include <stdio.h> 
#include <stdlib.h> 
#include <windows.h> 
#include <shellapi.h> 
 
int main( void ) 

HINSTANCE hNewExe = ShellExecuteA(NULL, "open", "d:\\tese.log", NULL, NULL, SW_SHOW); 
if ((DWORD)hNewExe <= 32) 

printf("return value:%d\n", (DWORD)hNewExe); 

else 

printf("successed!\n"); 

   printf("GetLastError: %d\n", GetLastError()); 
system("pause"); 
return 1; 

  


 當“D:\\test.log”文件不存在是,執行結果如下:
  這裡若函數執行錯誤, GetLastError()不一定能捕獲到錯誤代碼,例如當“d:\\tese.log”文件存在,將記事本"notepad.exe"命名為其他名字時:
  另外兩個函數的返回值就不列出了。
2、特殊用法
  1)如果將FileName參數設置為“http:”協議格式,那麼該函數將打開默認浏覽器並鏈接到指定的URL地址。若用戶機器中安裝了多個浏覽器,則該函數將根據Windows 9x/NT注冊表中http協議處理程序(Protocols Handler)的設置確定啟動哪個浏覽器。
  格式一:http://網站域名。       如:ShellExecute(handle, “open”, “http://www.neu.edu.cn”, nil, nil, SW_SHOWNORMAL);
  格式二:http://網站域名/網頁文件名。  如:ShellExecute(handle, “open”, “http://www.neu.edu.cn/default.htm”, nil, nil, SW_SHOWNORMAL);
  2)如果將FileName參數設置為“mailto:”協議格式,那麼該函數將啟動默認郵件客戶程序,如Microsoft Outlook(也包括Microsoft Outlook Express)或Netscape Messanger。若用戶機器中安裝了多個郵件客戶程序,則該函數將根據Windows 9x/NT注冊表中mailto協議處理程序的設置確定啟動哪個郵件客戶程序。
  格式一:mailto:     如:ShellExecute(handle, "open", "mailto:", nil, nil, SW_SHOWNORMAL);打開新郵件窗口。
  格式二:mailto:用戶賬號@郵件服務器地址 如:ShellExecute(handle, "open", "mailto:[email protected]", nil, nil, SW_SHOWNORMAL);
  打開新郵件窗口,並自動填入收件人地址。若指定多個收件人地址,則收件人地址之間必須用分號或逗號分隔開(下同)
如:ShellExecute(this->m_hWnd, "open", "mailto:[email protected]", "", "", SW_SHOW);
  格式三:mailto:用戶賬號@郵件服務器地址?subject=郵件主題&body=郵件正文
  如:ShellExecute(handle, "open", "mailto:[email protected]?subject=Hello&Body=This is a test", nil, nil, SW_SHOWNORMAL);
  打開新郵件窗口,並自動填入收件人地址、郵件主題和郵件正文。若郵件正文包括多行文本,則必須在每行文本之間加入換行轉義字符%0a。

例子(delphi):
在一個應用程序調用c:Project1.exe;
  ShellExecute(handle, ’open’,’c:Project1.exe’,’字串內容’,nil, SW_SHOWNORMAL);
在Project1.exe裡可以調用:
procedure TForm1.FormCreate(Sender: TObject);
var i:integer;
begin
for i:=1 to paramcount do
if ParamStr(i)〈〉’’ then showmessage(ParamStr(i));
end;
最後的那個參數,為窗口指定可視性方面的一個命令。 請用下述任何一個常數
SW_HIDE 隱藏窗口,活動狀態給令一個窗口
SW_MINIMIZE 最小化窗口,活動狀態給令一個窗口
SW_RESTORE 用原來的大小和位置顯示一個窗口,同時令其進入活動狀態
SW_SHOW 用當前的大小和位置顯示一個窗口,同時令其進入活動狀態
SW_SHOWMAXIMIZED 最大化窗口,並將其激活
SW_SHOWMINIMIZED 最小化窗口,並將其激活
SW_SHOWMINNOACTIVE 最小化一個窗口,同時不改變活動窗口
SW_SHOWNA 用當前的大小和位置顯示一個窗口,不改變活動窗口
SW_SHOWNOACTIVATE 用最近的大小和位置顯示一個窗口,同時不改變活動窗口
SW_SHOWNORMAL 與SW_RESTORE相同
  3、深入淺出ShellExecute 譯者:徐景周(原作:Nishant S)
Q: 如何打開一個應用程序? 正如您所看到的,我並沒有傳遞程序的完整路徑。
  ShellExecute(this->m_hWnd, "open", "calc.exe", "", "", SW_SHOW);
或ShellExecute(this->m_hWnd, "open", "notepad.exe", "c:\\MyLog.log", "", SW_SHOW);
Q: 如何打開一個同系統程序相關連的文檔?
ShellExecute(this->m_hWnd, "open", "c:\\abc.txt", "", "", SW_SHOW);
Q: 如何打開一個網頁?
ShellExecute(this->m_hWnd, "open", "http://www.BkJia.com", "", "", SW_SHOW);
Q: 如何激活相關程序,發送EMAIL?
ShellExecute(this->m_hWnd,"open", "mailto:[email protected]","","", SW_SHOW );
Q: 如何用系統打印機打印文檔?
ShellExecute(this->m_hWnd, "print", "c:\\abc.txt", "", "", SW_HIDE);
Q: 如何用系統查找功能來查找指定文件?
ShellExecute(m_hWnd, "find", "d:\\nish", NULL, NULL, SW_SHOW);
Q: 如何啟動一個程序,直到它運行結束?
    SHELLEXECUTEINFO ShExecInfo = {0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = NULL;
ShExecInfo.lpFile = "c:\\MyProgram.exe";
ShExecInfo.lpParameters = "";
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
WaitForSingleObject(ShExecInfo.hProcess,INFINITE);
  或:
PROCESS_INFORMATION ProcessInfo;
STARTUPINFO StartupInfo; //This is an [in] parameter
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
StartupInfo.cb = sizeof(StartupInfo); //Only compulsory field
if(CreateProcess("c:\\winnt\\notepad.exe", NULL, NULL,NULL,FALSE,0,NULL, NULL,&StartupInfo,&ProcessInfo))
{
WaitForSingleObject(ProcessInfo.hProcess,INFINITE);
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
}
else
{
MessageBox("The process could not be started...");
}
  Q: 如何顯示文件或文件夾的屬性?
SHELLEXECUTEINFO ShExecInfo = {0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_INVOKEIDLIST;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = "properties";
ShExecInfo.lpFile = "c:\\"; //can be a file as well
ShExecInfo.lpParameters = "";
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);

使用CreateProcess命令
  ⑴ 函數原型:
BOOL CreateProcess(
 LPCTSTR lpApplicationName,
 LPTSTR lpCommandLine,
 LPSECURITY_ATTRIBUTES lpProcessAttributes,
 LPSECURITY_ATTRIBUTES lpThreadAttributes,
 BOOL bInheritHandles,
 DWORD dwCreationFlags,
 LPVOID lpEnvironment,
 LPCTSTR lpCurrentDirectory,
 LPSTARTUPINFO lpStartupInfo,
 LPPROCESS_INFORMATION lpProcessInformation
);
  ⑵ 參數:
  lpApplicationName:指向一個以空結尾的串,他指定了要執行的模塊
  lpCommandLine:指向一個以空結尾的串,該串定義了要執行的命令行。
  lpProcessAttributes:指向一個SECURITY_ATTRIBUTES結構,該結構決定了返回的句柄是否可被子進程繼承。
  lpThreadAttributes:指向一個SECURITY_ATTRIBUTES結構,該結構決定了返回的句柄是否可被子進程繼承。
  bInheritHandles,:表明新進程是否從調用進程繼承句柄。
  dwCreationFlags:定義控制優先類和進程創建的附加標志。
  lpEnvironment:指向一個新進程的環境塊。
  lpCurrentDirectory:指向一個以空結尾的串,該串定義了子進程的當前驅動器和當前目錄。
  lpStartupInfo:指向一個STARTUPINFO結構,該結構定義了新進程的主窗口將如何顯示。
  lpProcessInformation:指向PROCESS_INFORMATION結構,該結構接受關於新進程的表示信息。
  ⑶ 返回值:
  若函數調用成功,則返回值不為0;若函數調用失敗,返回值為0。
  在上述參數中,參數lpStartupInfo是STARTUPINFO結構。可以用來設置控台的標題,新窗口的的初始大小和位置,及重定向標准輸入 和輸出。新程序通常可以忽略多數這些數據項,如果選擇那樣做的話。可以規定該結構體中的標志,已表明要設置的數據段。有時,不想設置任何信息,也必須傳遞 一個有效的指針給空結構(確定設置大小到cb,及設置dwFlags成員為0)。參數lpProcessInformation返回進程和線程句柄,還包 括進程和線程ID。這些句柄擁有在參數lpProcessAttributes和lpThreadAttributes中規定的訪問。
  要注意,針對CreateProcess的一些參數對控制台應用程序是特定的,而其它參數則對各種應用程序有用。大多數情況下,並不一定要填入 STARTUPINFO結構,但無論如何必須提供它。其返回值是布爾型的,而真正感興趣的返回值發生於作為參數傳送的結構中 (PROCESS_INFORMATION)。CreateProcess返回該結構中的進程ID及其句柄,以及初始線程ID及其句柄。可以將ID發送到 其它進程,或使用句柄來控制新進程。
  ShellExecute和WinExec命令用於簡單的作業。如果要完全控制一個新進程,就必須調用CreateProcess。


---------------------------------------------------------------------------------------------------------

三、注意事項

1、定義頭文件

在頭文件stdafx.h中必須定義以下兩個頭文件:

#include <shlobj.h> // 可替換為 windows.h
#include <shellapi.h>
如果定義了頭文件 #include <windows.h>的話就不必定義 #include <shlobj.h>了,"windows.h" 不光是包含了"shellapi.h",它還定義了許多數據類型,如果沒有這些數據類型,shellapi.h本身會出錯。


摘自 lanbing510的專欄
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved