在一個進程中啓動另一個進程---CreateProcess API

進程提供了程序運行所需要的資源,虛擬內存地址空間......
exe文件加載到進程的虛擬地址空間內存中指定的位置.

每個進程都有一個標識符(PID)和一個句柄,系統和其他進程可以通過PID和進程的句柄對進程進行管理操作

動態庫的原理
如:API函數CreateFile可執行代碼在Kernel32.dll中,"內存分頁管理"將多個虛擬內存分頁映射到同一個物理分頁上.

動態鏈接過程,exe文件中的導入表,初始化時將動態庫加載到內存的虛擬地址空間中.
"動態鏈接"和"靜態鏈接".

線程,纖程與作業
1.線程(Thread)
2.纖程(Fiber)
3.作業(Job,也稱爲工作項)
作業是一種對象,可以將一組進程作爲一個單元進行管理.
包括:命名對象(namable),安全對象(securable)和共享對象(sharable)

創建進程,獲取進程相關信息,獲取啓動函數
1.父進程和子進程
2.啓動參數
GetCommandLine,GetStartupInfo函數獲得啓動參數,啓動信息.
3.進程句柄和進程標識
如果想知道自己的句柄,可以使用
GetCurrentProcess和GetCurrentProcessId函數獲取自己的句柄和PID.
可以使用GetPriorityClass,GetProcessTimes,GetProcessVersion,GetProcessWorkingSetSize函數獲取進程的相關消息
獲得其他進程PID,可以通過OpenProcess函數獲得進程句柄,也可通過GetProcessId通過句柄獲得PID.

退出和終止程序
ExitProcess或TerminateProcess.

關鍵API
CreateProcess
另外還有CreateProcessAsUser,CreateProcessWithLogonW,CreateProcessWithTokenW.
WinExec函數功能也是執行程序.

BOOL WINAPI CreateProcess(
__in          LPCTSTR lpApplicationName, //指向啓動exe文件
__in_out      LPTSTR lpCommandLine, //啓動進程命令行
__in          LPSECURITY_ATTRIBUTES lpProcessAttributes, //SECURITY_ATTRIBUTES結構變量,爲進程設置安全屬性
__in          LPSECURITY_ATTRIBUTES lpThreadAttributes, //進程句柄是否可以被子進程繼承
__in          BOOL bInheritHandles, //與子進程句柄基礎關係
__in          DWORD dwCreationFlags, //進程創建標誌和優先級控制
__in          LPVOID lpEnvironment, //指向新進程環境變量塊,null指使用父進程環境變量塊
__in          LPCTSTR lpCurrentDirectory, //指定創建後新進程的當前目錄,null爲父進行的當前目錄
__in          LPSTARTUPINFO lpStartupInfo, //設定啓動信息,A pointer to a STARTUPINFO or STARTUPINFOEX 兩結構.
__out         LPPROCESS_INFORMATION lpProcessInformation //A pointer to a PROCESS_INFORMATION structure that receives identification information about the new process
);                                                          //返回進程信息

創建進程實例:
/* 頭文件 */
#include <windows.h>
#include <stdio.h>

DWORD CreateChildProcess(LPSTR szChildProcessCmd);

/*************************************
* int main(void)
* 功能 演示進程創建
*
* 參數 未使用
**************************************/
int main()
{
CreateChildProcess("Child.exe abc 123");
}
/*************************************
* DWORD CreateChildProcess(LPSTR szChildProcessCmd)
* 功能 演示創建子進程
*
* 參數 LPSTR szChildProcessCmd 啓動子進程的命令行
* 返回值 成功返回,失敗返回
**************************************/
DWORD CreateChildProcess(LPSTR szChildProcessCmd)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
// 將啓動信息結構清零
ZeroMemory( &si, sizeof(si) );
// 設置結構大小,cb屬性應爲結構的大小
si.cb = sizeof(si);
// 將進程信息結構清零
ZeroMemory( &pi, sizeof(pi) );

// 創建子進程,並判斷是否成功
if( !CreateProcess( NULL,   // 使用命令行
   szChildProcessCmd,    // 命令行
   NULL,             // 不繼承進程句柄
   NULL,             // 不繼承線程句柄
   FALSE,            // 不繼承句柄
   0,                // 沒有創建標誌
   NULL,             // 使用父進程環境變量
   NULL,             // 使用父進程目錄作爲當前目錄
   &si,              // STARTUPINFO 結構
   &pi )             // PROCESS_INFORMATION 保存相關信息
   )
{
   // 創建失敗
   printf( "CreateProcess failed (%d)./n", GetLastError() );
   return 1;
}
// 在創建成功後父進程也可直接退出,這裏等待子進程執行結束

// 等待子進程結束
// 使用到了通過PROCESS_INFORMATION 返回的相關信息,hProcess爲子進程句柄
// 父進程也可以不等待子進程運行完成而直接退出
WaitForSingleObject( pi.hProcess, INFINITE );
// 關閉進程句柄和線程句柄
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
return 0;
}

子進程:
/* 頭文件 */
#include <windows.h>
#include <stdio.h>
/* 宏定義 */
#define MyAlloc(size) HeapAlloc(GetProcessHeap(),0,size)
#define MyFree(lpMem) HeapFree(GetProcessHeap(),0,lpMem)
/* 結構體定義 */
typedef struct _PROCESS_INFO
{
DWORD dwPid;
HANDLE hProcess;
DWORD dwPrioClass;
DWORD dwHandleCount;
DWORD dwAffinityMask;
SIZE_T dwWorkingSetSizeMax;
SIZE_T dwWorkingSetSizeMin;
LPWSTR szwCommandLine;
STARTUPINFO sti;
}PROCESS_INFO, *LPPROCESS_INFO;
/* 全局變量 */
HANDLE hMySelf;
/* 函數聲明 */
DWORD GetProcessInfo(LPPROCESS_INFO lppi);

/*************************************
* int WinMain(
HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow
* 功能 演示獲取進程信息,在進程中獲取命令行參數等
*
**************************************/
int WinMain(
HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow
)
{
PROCESS_INFO pi;
INT argc;
WCHAR **argv;
DWORD i;
DWORD dwBufferSize = lstrlen(lpCmdLine)+MAX_PATH+1024;
LPSTR szShowBuffer = (LPSTR)MyAlloc(dwBufferSize);

hMySelf = hInstance;
// 顯示直接從WinMain函數參數得到的信息
wsprintf(szShowBuffer,
   "啓動參數/n實例句柄:%.8X,命令行參數:%s,顯示選項:%.8X",
   hInstance,lpCmdLine,nCmdShow);
MessageBox(NULL,szShowBuffer,"WinMain函數參數",MB_OK);
// 使用自定義的函數獲取相關信息
GetProcessInfo(&pi);
// 將命令行參數分離
argv = CommandLineToArgvW(pi.szwCommandLine,&argc);
// 字符處理,並顯示
*szShowBuffer = '/x00';
for(i=0; i<argc; i++)
{
   DWORD dwBufferSize = lstrlenW(*argv)+1;
   LPSTR szMBArgv = MyAlloc(dwBufferSize);
   WideCharToMultiByte(CP_ACP,0,*argv,-1,szMBArgv,dwBufferSize,NULL,NULL);
   argv++;
   lstrcat(szShowBuffer,"/n");
   lstrcat(szShowBuffer,szMBArgv);
   MyFree(szMBArgv);
}
MessageBox(NULL,szShowBuffer,"參數",MB_OK);
MyFree(szShowBuffer);
// 打印其他信息 TODO
return 0;
}
/*************************************
* DWORD GetProcessInfo(LPPROCESS_INFO lppi)
* 功能 獲取進程相關信息,保存在PROCESS_INFO結構中
*
* 參數 LPPROCESS_INFO lppi 用於保存相關信息
**************************************/
DWORD GetProcessInfo(LPPROCESS_INFO lppi)
{
// PID
lppi->dwPid = GetCurrentProcessId();
// 句柄
lppi->hProcess = GetCurrentProcess();
// 優先級
lppi->dwPrioClass = GetPriorityClass(hMySelf);
// 句柄記數
//windows xp sp1 sdk 新增的API GetProcessHandleCount
//lppi->dwHandleCount
// = GetProcessHandleCount(lppi->hProcess,&lppi->dwHandleCount);

// AffinityMask
GetProcessAffinityMask(hMySelf,
   &lppi->dwAffinityMask,
   NULL);
// WorkingSetSize
GetProcessWorkingSetSize(hMySelf,
   &lppi->dwWorkingSetSizeMin,
   &lppi->dwWorkingSetSizeMax);
lppi->szwCommandLine = GetCommandLineW();
// 啓動信息
GetStartupInfo(&lppi->sti);
return 0;
}

 

 

 

 

我們平時常用的:

啓動:  
  STARTUPINFO   Si;  
  PROCESS_INFORMATION   Pi;  
   
  memset(&Si,   0,   sizeof(STARTUPINFO));  
  Si.cb   =   sizeof(STARTUPINFO);  
  Si.dwFlags   =   STARTF_USESHOWWINDOW;  
  Si.wShowWindow   =   SW_SHOWNORMAL;  
   
  CreateProcess("c://windows//notepad.exe",NULL,NULL,NULL,FALSE,0,NULL,NULL,&Si,&Pi))  
   
  關閉:  
  重載OnClose  
   
  void   CXXXXDlg::OnClose()    
  {  
  TerminateProcess(Pi.hProcess,   0);  
  CDialog::OnClose();  
  }  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章