Delphi 使用CreateProcess創建進程並彈出進程PID值 (轉)


var
  ExeName:PChar;
  StartupInfo:TStartupInfo;
  ProcessInfo:TProcessInformation;
begin
  FillChar(ProcessInfo,sizeof(TProcessInformation),0);
  FillChar(StartupInfo,Sizeof(TStartupInfo),0);
  StartupInfo.cb:=Sizeof(TStartupInfo);
  StartupInfo.dwFlags:=STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow:=SW_SHOW;
  ExeName :='C:\Program Files\Internet Explorer\iexplore.exe'; //所創建進程路徑
  If CreateProcess(ExeName,nil,nil,nil,False,NORMAL_PRIORITY_CLASS,
    nil,nil,StartupInfo,ProcessInfo) then
  ShowMessage(IntToStr(ProcessInfo.dwProcessId));   //這里就是創建進程的PID值
end;

 

這樣就可以執行c:\test.exe
如果你要的PID是進程ID那么這個
piProcInfoGPS.dwProcessId就是PID。

當一個線程調用CreateProcess時,系統就會創建一個進程內核對象,其初始使用計數是1。
  該進程內核對象不是進程本身,而是操作系統管理進程時使用的一個較小的數據結構。可以將進程內核對象視為由進程的統計信息組成的一個較小的數據結構。然后,系統為新進程創建一個虛擬地址

空間,並將可執行文件或任何必要的D L L文件的代碼和數據加載到該進程的地址空間中。
  然后,系統為新進程的主線程創建一個線程內核對象(其使用計數為1)。與進程內核對象一樣,線程內核對象也是操作系統用來管理線程的小型數據結構。通過執行C / C + +運行期啟動代碼,該主

線程便開始運行,它最終調用WinMain、wWinMain、main或wmain函數。如果系統成功地創建了新進程和主線程,CreateProcess便返回TRUE。
  
  pszApplicationName和pszCommandLine參數分別用於設定新進程將要使用的可執行文件的名字和傳遞給新進程的命令行字符串
  pszCommandLine參數的原型是PTSTR。這意味着CreateProcess期望你將傳遞一個非常量字符串的地址。從內部來講,CreateProcess實際上並不修改你傳遞給它的命令行字符串。不過,在

CreateProcess返回之前,它將該字符串恢復為它的原始形式。
  如果命令行字符串不包含在文件映象的只讀部分中,就會出現違規訪問的問題。解決這個問題的最好辦法是在調用CreateProcess之前像下面這樣將常量字符串拷貝到臨時緩存中。當CreateProcess分

析pszCommandLine字符串時,它將查看字符串中的第一個標記,並假設該標記是想運行的可執行文件的名字。如果可執行文件的文件名沒有擴展名,便假設它的擴展名為.exe。CreateProcess也按下面

的順序搜索該可執行文件:
  1) 包含調用進程的. e x e文件的目錄。
  2) 調用進程的當前目錄。
  3) Wi n d o w s的系統目錄。
  4) Wi n d o w s目錄。
  5) PAT H環境變量中列出的目錄。
  如果文件名包含全路徑,系統將使用全路徑來查看可執行文件,並且不再搜索這些
  目錄。如果系統找到了可執行文件,那么它就創建一個新進程,並將可執行文件的代碼和數據
  映射到新進程的地址空間中。然后系統將調用C / C + +運行期啟動例程。
  這一切都是在pszApplicationName參數是NULL(99%以上的時候都應該屬於這種情況)時
  發生的。如果不傳遞NULL,可以將地址傳遞給pszApplicationName參數中包含想運行的可執行
  文件的名字的字符串。請注意,必須設定文件的擴展名,系統將不會自動假設文件名有一
  個.exe擴展名。CreateProcess假設該文件位於當前目錄中,除非文件名前面有一個路徑。如果在當前目錄中找不到該文件,CreateProcess將不會在任何其他目錄中查找該文件,它運行失敗了。
  
  可以使用psaProcess和psaThread參數分別設定進程對象和線程對象需要的安全性。,在這種情況下,系統為這些對象賦予默認安全性描述符。也可以指定兩
  個SECURITY_ATTRIBUTES結構,並對它們進行初始化,以便創建自己的安全性權限,並將它們賦予進程對象和線程對象。
  將SECURITY_ATTRIBUTES結構用於psaProcess和psaThread參數的另一個原因是,父進
  程將來生成的任何子進程都可以繼承這兩個對象句柄中的任何一個。
  
  fdwCreate參數用於標識標志,以便用於規定如何來創建新進程。
  
  pvEnvironment參數用於指向包含新進程將要使用的環境字符串的內存塊。,使子進程能夠繼承它的父進程正在使用的一組環境字符串。也可以
  使用GetEnvironmentStrings函數。
  該函數用於獲得調用進程正在使用的環境字符串數據塊的地址。可以使用該函數返回的地
  址,作為CreateProcess的pvEnvironment參數。如果為pvEnvironment參數傳遞NULL,那么這正
  是CreateProcess函數所做的操作。當不再需要該內存塊時,應該調用FreeEnvironmentString s函數將內存塊釋放。
  
  
  pszCurDir參數允許父進程設置子進程的當前驅動器和目錄。如果本參數是NULL,則新進程的工作目錄將與生成新進程的應用程序的目錄相同。如果本參數不是NULL,那么pszCurDi r
  必須指向包含需要的工作驅動器和工作目錄的以0結尾的字符串。注意,必須設定路徑中的驅
  動器名。
  
  
  psiStartInfo參數用於指向一個STARTUPINFO結構。
  當Windows創建新進程時,它將使用該結構的有關成員。大多數應用程序將要求生成的應
  用程序僅僅使用默認值。  如果未能將該結構的內容初始化為零,那么該結構的成員將包含調用線程的堆棧上的任何
  無用信息。將該無用信息傳遞給CreateProcess,將意味着有時會創建新進程,有時則不能創建
  新進程,完全取決於該無用信息。有一點很重要,那就是將該結構的未用成員設置為零,這樣,
  CreateProcess就能連貫一致地運行。不這樣做是開發人員最常見的錯誤。
    ppiProcInfo參數用於指向你必須指定的PROCESS_INFORMATION結構。CreateProcess在
  返回之前要對該結構的成員進行初始化。
  在創建進程的時候,系統為每個對象賦予一個初始使用計數值1。然后,在createProcess返回之前,該函數打開進程對象和線程對象,並將每個對象的與進程相關的句柄放入PROCESS_IN

FORMATION結構的hProcess和hThread成員中。當CreateProcess在內部打開這些對象時,每個對象的使用計數就變為2。
  在系統能夠釋放進程對象前,該進程必須終止運行(將使用計數遞減為1),並且
  父進程必須調用CloseHandle(再將使用計數遞減1,使之變為0)。同樣,若要釋放線程對象,
  該線程必須終止運行,父進程必須關閉線程對象的句柄。
  

  當進程內核對象創建后,系統賦予該對象一個獨一無二的標識號,系統中的其他任何進程
  內核對象都不能使用這個相同的I D號。線程內核對象的情況也一樣。當一個線程內核對象創建
  時,該對象被賦予一個獨一無二的、系統范圍的I D號。進程I D和線程I D共享相同的號碼池。
  這意味着進程和線程不可能擁有相同的I D 。另外,對象決不會被賦予0 作為其I D。在
  CreateProcess返回之前,它要用這些ID填入PROCESS_INFORMATION結構的dwProcessId和dwThre adId成員中。
  應用程序使用I D來跟蹤進程和線程,必須懂得系統會立即復用進程I D和線程I D
  系統無法記住每個進程的父進程的I D,但是,由於I D是被立即重復使用的,因此,等到獲
  得父進程的I D時,該I D可能標識了系統中一個完全不同的進程。父進程可能已經終止運行。如果應用程序想要與它的“創建者”進行通信,最好不要使用I D。應該定義一個持久性更
  好的機制,比如內核對象和窗口句柄等。
  若要確保進程I D或線程I D不被重復使用,唯一的方法是保證進程或線程的內核對象不會
  被撤消。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM