本文演示如何通过 CreateProcess 创建一个进程句柄和主线程句柄可以被继承的子进程。
BOOL CreateProcess(
LPCTSTR lpApplicationName, // name of executable module
LPTSTR lpCommandLine, // command line string
LPSECURITY_ATTRIBUTES LPSECURITY_ATTRIBUTES , // SD
LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
BOOL bInheritHandles, // handle inheritance option
DWORD dwCreationFlags, // creation flags
LPVOID lpEnvironment, // new environment block
LPCTSTR lpCurrentDirectory, // current directory name
LPSTARTUPINFO lpStartupInfo, // startup information
LPPROCESS_INFORMATION lpProcessInformation // process information);
CreateProcess 的第三,第四参数分别表示新进程的进程属性和主线程属性,如果希望创建一个新进程,使得新进程的进程句柄和主线程句柄在当前进程的句柄表中可以被继承,则需要对 LPSECURITY_ATTRIBUTES 进行设置。
下面通过一个例子来测试进程句柄继承。
代码中出现的路径,请在您的机器上做相应的修改。
主进程 InheritProcessHandle.exe
// InheritProcessHandle.cpp : Defines the entry point for the console application.
// 测试创建可继承的进程
#include "stdafx.h"
#include <WINDOWS.H>
int main(int argc, char* argv[])
{
// 创建一个进程句柄和主线程句柄可继承的进程A
SECURITY_ATTRIBUTES saProcess, saThread;
saProcess.nLength = sizeof(saProcess);
saProcess.lpSecurityDescriptor = NULL;
saProcess.bInheritHandle = TRUE;
saThread.nLength = sizeof(saThread);
saThread.lpSecurityDescriptor = NULL;
saThread.bInheritHandle = TRUE;
STARTUPINFO siA = {0};
siA.cb = sizeof(siA);
PROCESS_INFORMATION piA;
char szCmd[256] = "c:\\notepad.exe";
CreateProcess(NULL, szCmd, &saProcess, &saThread, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &siA, &piA);
// 创建进程B,继承当前进程句柄表中进程A的主线程句柄和A的进程句柄,句柄通过命令行参数传递给B进程
memset(szCmd, 0, 256);
sprintf(szCmd, "F:\\MyProjects\\InheritProcessHandle2\\Debug\\InheritProcessHandle2.exe %x %x", piA.hProcess, piA.hThread);
STARTUPINFO siB = {0};
siB.cb = sizeof(siB);
PROCESS_INFORMATION piB;
CreateProcess(NULL, szCmd, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &siB, &piB);
//printf("error: %d\n", GetLastError());
return 0;
}
子进程 InheritProcessHandle2.exe
// InheritProcessHandle2.cpp : Defines the entry point for the console application.
// 主进程通过 CreateProcess 创建该进程,两个命令行参数分别表示notepad的进程句柄和主线程句柄
// 在该进程中继承得到notepad的句柄,并对notepad进行控制操作
#include "stdafx.h"
#include <WINDOWS.H>
int main(int argc, char* argv[])
{
// 获取继承的notepad进程句柄和主线程句柄
DWORD dwProcessHandle = -1, dwThreadHandle = -1;
sscanf(argv[1], "%x", &dwProcessHandle);
sscanf(argv[2], "%x", &dwThreadHandle);
printf("进程句柄: %x 主线程句柄: %x\n", dwProcessHandle, dwThreadHandle);
// 挂起notepad
printf("挂起 notepad.exe 主线程5秒\n");
SuspendThread((HANDLE)dwThreadHandle);
Sleep(5000);
printf("恢复 notepad.exe 主线程.\n");
ResumeThread((HANDLE)dwThreadHandle);
printf("输入0关闭 notepad.exe 进程\n");
while (getchar() != '0');
TerminateProcess((HANDLE)dwProcessHandle, 1);
WaitForSingleObject((HANDLE)dwProcessHandle, INFINITE);
printf("notepad.exe 进程已关闭\n");
return 0;
}
主进程运行结果
子进程启动后,notepad进程被挂起5秒,可以看到notepad的界面已经阻塞
5秒后notepad恢复运行
子进程可以关闭notepad进程,通过继承notepad的进程句柄。