利用VC中函數調用一個.exe文件

以前總是感覺各大項目之間的結合很神奇,今日一見“不過如此”。

寫一個利用VC調用ACDSee打開一個圖片文件的簡單程序,於是瞭解了一些VC中調用其他程序的方法。


VC中調用其他程序的方法一般有三種,分別利用三個API函數WinExec,ShellExecute ,CreateProcess。其中WinExec最簡單,但較老;ShellExecute簡單靈活,較爲實用; CreateProcess則控制比較全面,但是較爲複雜。下面分別介紹一下這三種方法。

使用WinExec命令

  ⑴ 函數原型:

UINT WinExec(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命令

  1. 函數功能:

你可以給它任何文件的名字,它都能識別出來並打開它。

2.函數原型:


HINSTANCE ShellExecute(


HWND hwnd,


LPCTSTR lpOperation, 字串7


LPCTSTR lpFile,

LPCTSTR lpParameters,

LPCTSTR lpDirectory, 字串2

INT nShowCmd 字串5

); 字串5

3.參數說明:

hwnd: 字串3

用於指定父窗口句柄。當函數調用過程出現錯誤時,它將作爲Windows消息窗口的父窗口。

lpOperation:

用於指定要進行的操作。 字串4

“open”操作表示執行由lpFile參數指定的程序,或打開由lpFile參數指定的文件或文件夾;

“print”操作表示打印由lpFile參數指定的文件;


“explore”操作表示瀏覽由lpFile參數指定的文件夾。


當參數設爲NULL時,表示執行默認操作“open”。


lpFile:

用於指定要打開的文件名、要執行的程序文件名或要瀏覽的文件夾名。





lpParameters: 字串6


若lpFile參數是一個可執行程序,則此參數指定命令行參數,否則此參數應爲NULL.

lpDirectory: 字串3

用於指定默認目錄.





nShowCmd:

若lpFile參數是一個可執行程序,則此參數指定程序窗口的初始顯示方式,否則此參數應設置爲0。





這個參數常用的常數:

SW_HIDE 隱藏窗口,活動狀態給令一個窗口 字串5

SW_MINIMIZE 最小化窗口,活動狀態給令一個窗




SW_RESTORE 用原來的大小和位置顯示一個窗口,同時令其進入活動狀態


SW_SHOW 用當前的大小和位置顯示一個窗口,同時令其進入活動狀態





SW_SHOWMAXIMIZED 最大化窗口,並將其激活 字串6

SW_SHOWMINIMIZED 最小化窗口,並將其激活 字串3

SW_SHOWMINNOACTIVE 最小化一個窗口,同時不改變活動窗口 字串7

SW_SHOWNA 用當前的大小和位置顯示一個窗口,不改變活動窗口 字串9

SW_SHOWNOACTIVATE 用最近的大小和位置顯示一個窗口,同時不改變活動窗口




SW_SHOWNORMAL 與SW_RESTORE相同


若ShellExecute函數調用成功,則返回值爲被執行程序的實例句柄。若返回值小於32,則表示出現錯誤。

4.使用方法:


例如:


ShellExecute(NULL,"open","iloveu.bmp",NULL,NULL,SW_SHOWNORMAL);

用缺省的位圖編輯器打開一個叫iloveu.bmp的位圖文件,這個缺省的位圖編輯器可能是 Microsoft Paint, Adobe Photoshop, 或者 Corel PhotoPaint。

這個函數能打開任何文件,甚至是桌面和URL快捷方式( .ink或 .url)。ShellExecute解析系統註冊表HKEY_CLASSES_ROOT中所有的內容,判斷啓動那一個執行程序,並且啓動一個新的實例或使用DDE將文件名連到一打開的實例。然後,ShellExecute 返回打開文件的應用的實例句柄。 字串7

ShellExecute(NULL, "open", "http://www.microsoft.com", NULL, NULL, SW_SHOWNORMAL);





這個代碼使你能訪問微軟的主頁。當ShellExecute遇到文件名前面的“http:”時,可以判斷出要打開的文件是Web文件,隨之啓動Internet Explorer 或者 Netscape Navigator 或者任何你使用的別的瀏覽器打開文件。

ShellExecute還能識別其它協議,象FTP、GOPHER。甚至識別“mailto”,如果文件名指向“mailto:[email protected]”,它啓動電子郵件程序並打開一個待編輯的新郵件,例如:字串8

ShellExecute(NULL, "open",“mailto:[email protected]”, NULL, NULL, SW_SHOWNORMAL);打開新郵件窗口。




總之,ShellExecute函數就是如此簡單地打開磁盤文件和Internet文件。如果將第二個參數“OPEN”改爲“PRINT”或者“EXPLORE”,ShellExecute將能打印文件和打開文件夾。ShellExecute還有一個擴展函數ShellExecuteEx,所帶參數中有一個特殊的結構,功能更強,或者任何你使用的別的瀏覽器打開文件。

使用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。

  ShellExecute和WinExec命令用於簡單的作業。如果要完全控制一個新進程,就必須調用CreateProcess。

  在上述參數中,參數lpStartupInfo是STARTUPINFO結構。可以用來設置控臺的標題,新窗口的的初始大小和位置,及重定向標準輸入和輸出。新程序通常可以忽略多數這些數據項,如果選擇那樣做的話。可以規定該結構體中的標誌,已表明要設置的數據段。有時,不想設置任何信息,也必須傳遞一個有效的指針給空結構(確定設置大小到cb,及設置dwFlags成員爲0)。參數lpProcessInformation返回進程和線程句柄,還包括進程和線程ID。這些句柄擁有在參數lpProcessAttributes和lpThreadAttributes中規定的訪問。

  要注意,針對CreateProcess的一些參數對控制檯應用程序是特定的,而其它參數則對各種應用程序有用。大多數情況下,並不一定要填入STARTUPINFO結構,但無論如何必須提供它。其返回值是布爾型的,而真正感興趣的返回值發生於作爲參數傳送的結構中(PROCESS_INFORMATION)。CreateProcess返回該結構中的進程ID及其句柄,以及初始線程ID及其句柄。可以將ID發送到其它進程,或使用句柄來控制新進程。

關於三個API函數: WinExec, ShellExecute,CreateProcess 的其他注意事項:
1、定義頭文件
在頭文件stdafx.h中必須定義以下兩個頭文件:
#include <shlobj.h> // 可替換爲 windows.h
#include <shellapi.h>
如果定義了頭文件 #include <windows.h>的話就不必定義 #include <shlobj.h>了,"windows.h" 不光是包含了"shellapi.h",它還定義了許多數據類型,如果沒有這些數據類型,shellapi.h本身會出錯。
2、定義路徑
C++中所表示的路徑要用 " \\ "而不是平常所用的" \ ",所以以上三個函數表示路徑都爲:
Disk:\\Directory\\...\\File name
WinExec("D:\\Program Files\\Test\\Test.exe",SW_SHOWMAXIMIZED);
ShellExecute(NULL,"open","C:\\Test.txt",NULL,NULL,SW_SHOWNORMAL);
bool fRet=CreateProcess("D:\\putty.exe",NULL,NULL,FALSE,NULL,NULL,NULL,NULL,&si,&pi);



例如,打開一個圖片文件test.jpg有幾種簡單的打開方式。

::WinExec(

"D:\\ACDSee\\ACDSee9.exe \"F:\\code\\Visual C++\\Open_Exam1\\test.jpg\"",

//或者" ACDSee9.exe C:\\test.jpg",

SW_SHOW);



::ShellExecute(NULL,

"open",

"\"F:\\code\\Visual C++\\Open_Exam1\\test.jpg\"",

//或者” C:\\test.jpg”,

NULL,

NULL,

SW_SHOWNORMAL);



::ShellExecute(NULL,

"open",

" D:\\ACDSee\\ ",

//或者” ACDSee9.exe”,

"\"F:\\code\\Visual C++\\Open_Exam1\\test.jpg\"",

//或者” C:\\test.jpg”,

NULL,

SW_SHOWNORMAL);

注意:

1、 WinExec中第一個參數爲ACDSee.exe的完全路徑,也可以直接用” ACDSee9.exe”做參數,因爲它已經註冊到windows系統當中了。

2、 在寫要打開的文件的路徑時,如果路徑中有空格,應該用引號將其括起來,即再在外層包一層引號。

3、 ShellExecute可以有兩種方式打開test.jpg文件,一種是直接test.jpg打開,它會默認用ACDSee打開;另一種是先調用ACDSee軟件,再打開文件。這兩種方式在界面上有一點區別,視需求而定。

附:ShellExecute與ShellExecuteEx的用法

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.google.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);
發佈了7 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章