天天看點

ShellExecute, WinExec, CreateProcess差別 ShellExecute, WinExec, CreateProcess差別

ShellExecute, WinExec, CreateProcess差別

ShellExecute

  ShellExecute的功能是運作一個外部程式(或者是打開一個已注冊的檔案、打開一個目錄、列印一個檔案等等),并對外部程式有一定的控制。

  有幾個API函數都可以實作這些功能,但是在大多數情況下ShellExecute是更多的被使用的,同時它并不是太複雜。

  ShellExecute函數原型及參數含義如下:

  ShellExecute(

  HWND hwnd,           //父視窗句柄 (如:NULL,Handle等)

  LPCSTR lpOperation, //操作類型 (如:"open")*要加英文雙引号

  LPCSTR lpFile,           //要進行操作的檔案或路徑

  LPCSTR lpParameters, //當lpOperation為“explore”時指定要傳遞的參數,通常設為NULL

  LPCSTR lpDirectory,    //指定預設目錄,通常設為NULL

  INT nShowCmd          //檔案打開的方式,以通常方式還是最大化或最小化顯示,一般為SW_SHOWNORMAL

  ) 

參數說明:

  ●hWnd:用于指定父視窗句柄。當函數調用過程出現錯誤時,它将作為Windows消息視窗的父視窗。例如,可以将其設定為應用程式主視窗句柄,即Application.Handle,也可以将其設定為桌面視窗句柄(用GetDesktopWindow函數獲得)。

  ●Operation:用于指定要進行的操作。其中“open”操作表示執行由FileName參數指定的程式,或打開由FileName參數指定的檔案或檔案夾;“print”操作表示列印由FileName參數指定的檔案;“explore”操作表示浏覽由FileName參數指定的檔案夾。當參數設為nil時,表示執行預設操作“open”。

  ●FileName:用于指定要打開的檔案名、要執行的程式檔案名或要浏覽的檔案夾名。

  ●Parameters:若FileName參數是一個可執行程式,則此參數指定指令行參數,否則此參數應為nil或PChar(0)。

  ●Directory:用于指定預設目錄。

  ●ShowCmd:若FileName參數是一個可執行程式,則此參數指定程式視窗的初始顯示方式,否則此參數應設定為0。

  若ShellExecute函數調用成功,則傳回值為被執行程式的執行個體句柄。若傳回值小于32,則表示出現錯誤。

  上述僅僅是ShellExecute函數的标準用法,下面将介紹它的特殊用法。 

例子如下:

  //調用記事本

  ShellExecute(NULL,"open","NOTEPAD.EXE",NULL,NULL,SW_SHOWNORMAL);

  2.特殊用法

  如果将FileName參數設定為“http:”協定格式,那麼該函數将打開預設浏覽器并連結到指定的URL位址。若使用者機器中安裝了多個浏覽器,則該函數将根據Windows 9x/NT系統資料庫中http協定處理程式(Protocols Handler)的設定确定啟動哪個浏覽器。

  格式一:http://網站域名。

  如:ShellExecute(Handle, "open", http:// ;

  www.neu.edu.cn’, NULL, NULL, SW_SHOWNORMAL);

  格式二:http://網站域名/網頁檔案名。

  如:ShellExecute(Handle, "open", http:// ;

  www.neu.edu.cn/default.htm',NULL,NULL,

  SW_SHOWNORMAL);

  如果将FileName參數設定為“mailto:”協定格式,那麼該函數将啟動預設郵件客戶程式,如Microsoft Outlook(也包括Microsoft Outlook Express)或Netscape Messanger。若使用者機器中安裝了多個郵件客戶程式,則該函數将根據Windows 9x/NT系統資料庫中mailto協定處理程式的設定确定啟動哪個郵件客戶程式。

  格式一:mailto:

  如:ShellExecute(Handle,"open", "mailto:", NULL, NULL, SW_SHOWNORMAL);打開新郵件視窗。

  格式二:mailto:使用者賬号@郵件伺服器位址

  如:ShellExecute(Handle, "open"," mailto:[email protected]", NULL, NULL, SW_SHOWNORMAL);打開新郵件視窗,并自動填入收件人位址。若指定多個收件人位址,則收件人位址之間必須用分号或逗号分隔開(下同)。

  格式三: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相同

WinExec

//聲明

WinExec(

  lpCmdLine: LPCSTR; {檔案名和參數; 如沒指定路徑會按以下順序查找: 程式目錄/目前目錄/System32/Windows/PATH環境變量}

  uCmdShow: UINT     {啟動選項}

): UINT;

//說明 :運作指定的程式

//傳回值 

大于 31                    {調用成功}

等于 0 {記憶體不足}

ERROR_FILE_NOT_FOUND = 2;  {檔案名錯誤}

ERROR_PATH_NOT_FOUND = 3;  {路徑名錯誤}

ERROR_BAD_FORMAT     = 11; {EXE 檔案無效}

(請參考FindExecutable函數)

//參數表: 

參數 類型及說明 

lpCmdLine String,包含要執行的指令行 

uCmdShow Long,定義了以怎樣的形式啟動程式的常數值。

//uCmdShow 參數可選值:

SW_HIDE            = 0; {隐藏, 并且工作列也沒有最小化圖示} SW_SHOWNORMAL = 1; {用最近的大小和位置顯示, 激活}

SW_NORMAL          = 1; {同 SW_SHOWNORMAL}

SW_SHOWMINIMIZED   = 2; {最小化, 激活}

SW_SHOWMAXIMIZED   = 3; {最大化, 激活}

SW_MAXIMIZE        = 3; {同 SW_SHOWMAXIMIZED}

SW_SHOWNOACTIVATE  = 4; {用最近的大小和位置顯示, 不激活}

SW_SHOW            = 5; {同 SW_SHOWNORMAL}

SW_MINIMIZE        = 6; {最小化, 不激活}

SW_SHOWMINNOACTIVE = 7; {同 SW_MINIMIZE}

SW_SHOWNA          = 8; {同 SW_SHOWNOACTIVATE}

SW_RESTORE         = 9; {同 SW_SHOWNORMAL}

SW_SHOWDEFAULT     = 10; {同 SW_SHOWNORMAL}

SW_MAX             = 10; {同 SW_SHOWNORMAL} 

CreateProcess

  說明:

  WIN32API函數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:指向一個NULL結尾的、用來指定可執行子產品的字元串。

  這個字元串可以使可執行子產品的絕對路徑,也可以是相對路徑,在後一種情況下,函數使用目前驅動器和目錄建立可執行子產品的路徑。

  這個參數可以被設為NULL,在這種情況下,可執行子產品的名字必須處于 lpCommandLine 參數的最前面并由空格符與後面的字元分開。

  這個被指定的子產品可以是一個Win32應用程式。如果适當的子系統在目前計算機上可用的話,它也可以是其他類型的子產品(如MS-DOS 或 OS/2)。

  在Windows NT中,如果可執行子產品是一個16位的應用程式,那麼這個參數應該被設定為NULL并且因該在lpCommandLine參數中指定可執行子產品的名稱。16位的應用程式是以DOS虛拟機或Win32上的Windows(WOW) 為程序的方式運作。

  lpCommandLine:指向一個NULL結尾的、用來指定要運作的指令行。

  這個參數可以為空,那麼函數将使用參數指定的字元串當作要運作的程式的指令行。

  如果lpApplicationName和lpCommandLine參數都不為空,那麼lpApplicationName參數指定将要被運作的子產品,lpCommandLine參數指定将被運作的子產品的指令行。新運作的程序可以使用GetCommandLine函數獲得整個指令行。C語言程式可以使用argc和argv參數。

  如果lpApplicationName參數為空,那麼這個字元串中的第一個被空格分隔的要素指定可執行子產品名。如果檔案名不包含擴充名,那麼.exe将被假定為預設的擴充名。如果檔案名以一個點(.)結尾且沒有擴充名,或檔案名中包含路徑,.exe将不會被加到後面。如果檔案名中不包含路徑,Windows将按照如下順序尋找這個可執行檔案:

  1.目前應用程式的目錄。

  2.父程序的目錄。

  3.Windows 95:Windows系統目錄,可以使用GetSystemDirectory函數獲得。

  Windows NT:32位Windows系統目錄。可以使用GetSystemDirectory函數獲得,目錄名是SYSTEM32。

  4.在Windows NT中:16位Windows系統目錄。不可以使用Win32函數獲得這個目錄,但是它會被搜尋,目錄名是SYSTEM。

  5.Windows目錄。可以使用GetWindowsDirectory函數獲得這個目錄。

  6.列在PATH環境變量中的目錄。

  如果被建立的程序是一個以MS-DOS或16位Windows為基礎的應用程式,lpCommandLine參數應該是一個以可執行檔案的檔案名作為第一個要素的絕對路徑,因為這樣做可以使32位Windows程式工作的很好,這樣設定lpCommandLine參數是最強壯的。

  lpProcessAttributes:指向一個SECURITY_ATTRIBUTES結構體,這個結構體決定是否傳回的句柄可以被子程序繼承。如果lpProcessAttributes參數為空(NULL),那麼句柄不能被繼承。

  在Windows NT中:SECURITY_ATTRIBUTES結構的lpSecurityDescriptor成員指定了新程序的安全描述符,如果參數為空,新程序使用預設的安全描述符。

  在Windows95中:SECURITY_ATTRIBUTES結構的lpSecurityDescriptor成員被忽略。

  lpThreadAttributes:指向一個SECURITY_ATTRIBUTES結構體,這個結構體決定是否傳回的句柄可以被子程序繼承。如果lpThreadAttributes參數為空(NULL),那麼句柄不能被繼承。

  在Windows NT中,SECURITY_ATTRIBUTES結構的lpSecurityDescriptor成員指定了主線程的安全描述符,如果參數為空,主線程使用預設的安全描述符。

  在Windows95中:SECURITY_ATTRIBUTES結構的lpSecurityDescriptor成員被忽略。

  bInheritHandles:訓示新程序是否從調用程序處繼承了句柄。如果參數的值為真,調用程序中的每一個可繼承的打開句柄都将被子程序繼承。被繼承的句柄與原程序擁有完全相同的值和通路權限。

  dwCreationFlags:指定附加的、用來控制優先類和程序的建立的标志。以下的建立标志可以以除下面列出的方式外的任何方式組合後指定。

  值:CREATE_DEFAULT_ERROR_MODE

  含義:新的程序不繼承調用程序的錯誤模式。CreateProcess函數賦予新程序目前的預設錯誤模式作為替代。應用程式可以調用SetErrorMode函數設定目前的預設錯誤模式。

  這個标志對于那些運作在沒有硬體錯誤環境下的多線程外殼程式是十分有用的。

  對于CreateProcess函數,預設的行為是為新程序繼承調用者的錯誤模式。設定這個标志以改變預設的處理方式。

  值:CREATE_NEW_CONSOLE

  含義:新的程序将使用一個新的控制台,而不是繼承父程序的控制台。這個标志不能與DETACHED_PROCESS标志一起使用。

  值:CREATE_NEW_PROCESS_GROUP

  含義:新程序将使一個程序樹的根程序。程序樹種的全部程序都是根程序的子程序。新程序樹的使用者辨別符與這個程序的辨別符是相同的,由 lpProcessInformation參數傳回。程序樹經常使用GenerateConsoleCtrlEvent函數允許發送CTRL+C或 CTRL+BREAK信号到一組控制台程序。

  值:CREATE_SEPARATE_WOW_VDM

  含義:(隻适用于 Windows NT)這個标志隻有當運作一個16位的Windows應用程式時才是有效的。如果被設定,新程序将會在一個私有的虛拟DOS機(VDM)中運作。另外,預設情況下所有的16位Windows應用程式都會在同一個共享的VDM中以線程的方式運作。單獨運作一個16位程式的優點是一個應用程式的崩潰隻會結束這一個VDM的運作;其他那些在不同VDM中運作的程式會繼續正常的運作。同樣的,在不同VDM中運作的16位Windows應用程式擁有不同的輸入隊列,這意味着如果一個程式暫時失去響應,在獨立的VDM中的應用程式能夠繼續獲得輸入。

  值:CREATE_SHARED_WOW_VDM

  含義:(隻适用于Windows NT)這個标志隻有當運作一個16位的Windows應用程式時才是有效的。如果WIN.INI中的Windows段的 DefaultSeparateVDM選項被設定為真,這個辨別使得CreateProcess函數越過這個選項并在共享的虛拟DOS機中運作新程序。

  值:CREATE_SUSPENDED

  含義:新程序的主線程會以暫停的狀态被建立,直到調用ResumeThread函數被調用時才運作。

  值:CREATE_UNICODE_ENVIRONMENT

  含義:如果被設定,由lpEnvironment參數指定的環境塊使用Unicode字元,如果為空,環境塊使用ANSI字元。

  值:DEBUG_PROCESS

  含義:如果這個标志被設定,調用程序将被當作一個調試程式,并且新程序會被當作被調試的程序。系統把被調試程式發生的所有調試事件通知給調試器。

  如果你使用這個标志建立程序,隻有調用程序(調用CreateProcess函數的程序)可以調用WaitForDebugEvent函數。

  值:DEBUG_ONLY_THIS_PROCESS

  含義:如果此标志沒有被設定且調用程序正在被調試,新程序将成為調試調用程序的調試器的另一個調試對象。如果調用程序沒有被調試,有關調試的行為就不會産生。

  值:DETACHED_PROCESS

  含義:對于控制台程序,新程序沒有通路父程序控制台的權限。新程序可以通過AllocConsole函數自己建立一個新的控制台。這個标志不可以與CREATE_NEW_CONSOLE标志一起使用。

  dwCreationFlags參數還用來控制新程序的優先類,優先類用來決定此程序的線程排程的優先級。如果下面的優先級類标志都沒有被指定,那麼預設的優先類是NORMAL_PRIORITY_CLASS,除非被建立的程序是IDLE_PRIORITY_CLASS。在這種情況下子程序的預設優先類是IDLE_PRIORITY_CLASS。

  可以下面的标志中的一個:

  優先級:HIGH_PRIORITY_CLASS 

  含義:訓示這個程序将執行時間臨界的任務,是以它必須被立即運作以保證正确。這個優先級的程式優先于正常優先級或空閑優先級的程式。一個例子是 Windows任務清單,為了保證當使用者調用時可以立刻響應,放棄了對系統負荷的考慮。確定在使用高優先級時應該足夠謹慎,因為一個高優先級的CPU關聯應用程式可以占用幾乎全部的CPU可用時間。

  優先級:IDLE_PRIORITY_CLASS 

  含義:訓示這個程序的線程隻有在系統空閑時才會運作并且可以被任何高優先級的任務打斷。例如螢幕保護程式。空閑優先級會被子程序繼承。

  優先級:NORMAL_PRIORITY_CLASS 

  含義:訓示這個程序沒有特殊的任務排程要求。

  優先級:REALTIME_PRIORITY_CLASS 

  含義:訓示這個程序擁有可用的最高優先級。一個擁有實時優先級的程序的線程可以打斷所有其他程序線程的執行,包括正在執行重要任務的系統程序。例如,一個執行時間稍長一點的實時程序可能導緻磁盤緩存不足或滑鼠反映遲鈍。

  lpEnvironment:指向一個新程序的環境塊。如果此參數為空,新程序使用調用程序的環境。

  一個環境塊存在于一個由以NULL結尾的字元串組成的塊中,這個塊也是以NULL結尾的。每個字元串都是name=value的形式。

  因為相等标志被當作分隔符,是以它不能被環境變量當作變量名。

  與其使用應用程式提供的環境塊,不如直接把這個參數設為空,系統驅動器上的目前目錄資訊不會被自動傳遞給新建立的程序。對于這個情況的探讨和如何處理,請參見注釋一節。

  環境塊可以包含Unicode或ANSI字元。如果lpEnvironment指向的環境塊包含Unicode字元,那麼 dwCreationFlags字段的CREATE_UNICODE_ENVIRONMENT标志将被設定。如果塊包含ANSI字元,該标志将被清空。

  請注意一個ANSI環境塊是由兩個零位元組結束的:一個是字元串的結尾,另一個用來結束這個快。一個Unicode環境塊石油四個零位元組結束的:兩個代表字元串結束,另兩個用來結束塊。

  lpCurrentDirectory:指向一個以NULL結尾的字元串,這個字元串用來指定子程序的工作路徑。這個字元串必須是一個包含驅動器名的絕對路徑。如果這個參數為空,新程序将使用與調用程序相同的驅動器和目錄。這個選項是一個需要啟動啟動應用程式并指定它們的驅動器和工作目錄的外殼程式的主要條件。

  lpStartupInfo:指向一個用于決定新程序的主窗體如何顯示的STARTUPINFO結構體。

  lpProcessInformation:指向一個用來接收新程序的識别資訊的PROCESS_INFORMATION結構體。

  傳回值:

  如果函數執行成功,傳回非零值。

  如果函數執行失敗,傳回零,可以使用GetLastError函數獲得錯誤的附加資訊。

  注釋:

  CreateProcess函數用來運作一個新程式。WinExec和LoadModule函數依舊可用,但是它們同樣通過調用CreateProcess函數實作。

  另外CreateProcess函數除了建立一個程序,還建立一個線程對象。這個線程将連同一個已初始化了的堆棧一起被建立,堆棧的大小由可執行檔案的檔案頭中的描述決定。線程由檔案頭處開始執行。

  新程序和新線程的句柄被以全局通路權限建立。對于這兩個句柄中的任一個,如果沒有安全描述符,那麼這個句柄就可以在任何需要句柄類型作為參數的函數中被使用。當提供安全描述符時,在接下來的時候當句柄被使用時,總是會先進行通路權限的檢查,如果通路權限檢查拒絕通路,請求的程序将不能使用這個句柄通路這個程序。

  這個程序會被配置設定給一個32位的程序辨別符。直到程序中止這個辨別符都是有效的。它可以被用來辨別這個程序,或在 OpenProcess函數中被指定以打開這個程序的句柄。程序中被初始化了的線程一樣會被配置設定一個32位的線程辨別符。這個辨別符直到縣城中止都是有效的且可以用來在系統中唯一辨別這個線程。這些辨別符在PROCESS_INFORMATION結構體中傳回。

  當在lpApplicationName或lpCommandLine參數中指定應用程式名時,應用程式名中是否包含擴充名都不會影響運作,隻有一種情況例外:一個以.com為擴充名的MS-DOS程式或Windows程式必須包含.com擴充名。

  調用程序可以通過WaitForInputIdle函數來等待新程序完成它的初始化并等待使用者輸入。這對于父程序和子程序之間的同步是極其有用的,因為 CreateProcess函數不會等待新程序完成它的初始化工作。舉例來說,在試圖與新程序關聯的視窗之前,程序應該先調用 WaitForInputIdle。

  首選的結束一個程序的方式是調用ExitProcess函數,因為這個函數通知這個程序的所有動态連結庫(DLLs)程式已進入結束狀态。其他的結束程序的方法不會通知關聯的動态連結庫。注意當一個程序調用ExitProcess時,這個程序的其他縣城沒有機會運作其他任何代碼(包括關關聯态連結庫的終止代碼)。

  ExitProcess, ExitThread, CreateThread, CreateRemoteThread,當一個程序啟動時(調用了CreateProcess的結果)是在程序中序列化進行的。在一段位址空間中,同一時間内這些事件中隻有一個可以發生。這意味着下面的限制将保留:

  *在程序啟動和DLL初始化階段,新的線程可以被建立,但是直到程序的DLL初始化完成前它們都不能開始運作。

  *在DLL初始化或卸下例程中程序中隻能有一個線程。

  *直到所有的線程都完成DLL初始化或卸下後,ExitProcess函數才傳回。

  在程序中的所有線程都終止且程序所有的句柄和它們的線程被通過調用CloseHandle函數終止前,程序會留在系統中。程序和主線程的句柄都必須通過調用CloseHandle函數關閉。如果不再需要這些句柄,最好在建立程序後立刻關閉它們。

  當程序中最後一個線程終止時,下列的事件發生:

  *所有由程序打開的對象都會關閉。

  *程序的終止狀态(由GetExitCodeProcess函數傳回)從它的初始值STILL_ACTIVE變為最後一個結束的線程的結束狀态。

  *主線程的線程對象被設定為标志狀态,供其他等待這個對象的線程使用。

  *程序對象被設定為标志狀态,供其他等待這個對象的線程使用。

  假設目前在C槽上的目錄是\MSVC\MFC且有一個環境變量叫做C:,它的值是C:\MSVC\MFC,就像前面lpEnvironment中提到過的那樣,這樣的系統驅動器上的目錄資訊在CreateProcess函數的lpEnvironment參數不為空時不會被自動傳遞到新程序裡。一個應用程式必須手動地把目前目錄資訊傳遞到新的程序中。為了這樣做,應用程式必須直接建立環境字元串,并把它們按字母順序排列(因為Windows NT和Windows 95使用一種簡略的環境變量),并把它們放進lpEnvironment中指定的環境塊中。類似的,他們要找到環境塊的開頭,又要重複一次前面提到的環境塊的排序。

  一種獲得驅動器X的目前目錄變量的方法是調用GetFullPathName("x:",..)。這避免了一個應用程式必須去掃描環境塊。如果傳回的絕對路徑是X:\,就不需要把這個值當作一個環境資料去傳遞了,因為根目錄是驅動器X上的新程序的預設目前目錄。

  由CreateProcess函數傳回的句柄對于程序對象具有PROCESS_ALL_ACCESS的通路權限。

  由lpcurrentDirectory參數指定的目前目錄室子程序對象的目前目錄。lpCommandLine參數指定的第二個項目是父程序的目前目錄。

  對于Windows NT,當一個程序在指定了CREATE_NEW_PROCESS_GROUP的情況下被建立時,一個對于 SetConsoleCtrlHandler(NULL,True)的調用被用在新的程序上,這意味着對新程序來說CTRL+C是無效的。這使得上層的外科程式可以自己處理CTRL+C資訊并有選擇的把這些信号傳遞給子程序。CTRL+BREAK依舊有效,并可被用來中斷程序/程序樹的執行。

  安全注釋:

  第一個參數lpApplicationName可能是空,這種情況下,可執行檔案的名字必須在lpCommandLine 中,lpCommandLine參數中可以包含空格。如果可執行檔案或路徑中包含空格,那麼就會有執行不正确檔案的風險,這是由于這個函數解析空格的方法引起的。例如:下邊這個例子就很危險,因為它試圖運作Program.exe檔案,如果這個檔案存在,它就會代替MyApp.exe檔案的運作。

  CreateProcess(NULL,”C:\\Program Files\\MyApp.exe”,…….)

  如果有惡意的使用者在系統編寫了一個名為Program.exe的檔案,那麼任何調用CreateProcess函數,且在檔案路徑中使用Program Files檔案夾的參數,都有可能會運作Program.exe檔案,而不是運作本來打算運作的檔案。

  要避免這個問題,可以不要将NULL值傳遞給lpApplicationName參數,或者在lpCommandLine中使用雙引号(轉義符)括起可執行檔案的全路徑名,如下所示:

  CreateProcess(NULL,”\”C:\\Program Files\\MyApp.exe\” -L -S”,…….)

  -L和-S是MyApp.exe可執行檔案的參數。

  最後要說明的一點是:在lpApplicationName中的參數和lpCommandLine中的第一個參數是一樣的,有人說顯得有些重複,其實這樣做純粹是一種被公認化了習慣!

  參見

  AllocConsole, CloseHandle, CreateRemoteThread, CreateThread, ExitProcess, ExitThread, GenerateConsoleCtrlEvent, GetCommandLine, GetEnvironmentStrings, GetExitCodeProcess, GetFullPathName, GetStartupInfo, GetSystemDirectory, GetWindowsDirectory, LoadModule, OpenProcess, PROCESS_INFORMATION, ResumeThread, SECURITY_ATTRIBUTES, SetConsoleCtrlHandler, SetErrorMode, STARTUPINFO, TerminateProcess, WaitForInputIdle, WaitForDebugEvent, WinExec

  快捷資訊:

  導入庫:kernel32.lib

  頭檔案:Winbase.h 

  簡單例子:

  #include <iostream>

  #include<windows.h>

  using namespace std;

  int main()

  {

  TCHAR szCmdLine[]={TEXT("d:\\test\\te.exe")};//added by 江湖三腳貓 2009-4-28

  STARTUPINFO si; //一些必備參數設定

  memset(&si, 0, sizeof(STARTUPINFO)); 

  si.cb = sizeof(STARTUPINFO); 

  si.dwFlags = STARTF_USESHOWWINDOW; 

  si.wShowWindow = SW_SHOW; 

  PROCESS_INFORMATION pi; //必備參數設定結束

  //lpCommandLine不能寫成"d:\\test\\te.exe"常量形式 ,改成 TCHAR szCmdLine[]={"d:\\test\\te.exe"}

  //lpCommandLine需要改成 TCHAR szCmdLine[]={TEXT("d:\\test\\te.exe")};

  if(!CreateProcess(NULL,szCmdLine,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi))

  //if(!CreateProcess(NULL,"d:\\test\\te.exe",NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)) //"d:\\test\\te.exe"是您要運作的程式//的路徑

  {

  cout<<"Create Fail!"<<endl;

  exit(1);

  }

  else

  {

  cout<<"Sucess!"<<endl;

  }

  return 0;

  }

差別:

功能上: createprocess   >   shellexecute   >   winexec   複雜程度也是!

winexec() 隻用于可執行檔案,是一個老函數啦,雖然使用友善,但不推薦!(相容性也不好)

shellexcute()是通過windows外殼打開任意檔案,非可執行檔案自動通過關聯的程式打開對于可執行檔案,差別不大,不過shellexcute可以指定運作時的工作路徑

winexec() 必須有GetMessage或逾時之後才傳回!CreateProcess和ShellExecute都是直接傳回的!

本文來自CSDN部落格,轉載請标明出處:http://blog.csdn.net/duck04551/archive/2009/07/01/4312260.aspx

繼續閱讀