進程提供了程序運行所需要的資源,虛擬內存地址空間......
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();
}