1. 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则执行自动搜索可用目录(当前目录, system32, PATH路径目录等)的exe文件, 不为NULL,则只限定在当前目录
lpThreadAttributes: 一般设为NULL
bInheritHandles: 一般设为TRUE
dwCreationFlags: 新进程创建的方式和优先级,执行命令一般采用CREATE_NEW_CONSOLE |NORMAL_PRIORITY_CLASS(默认优先级)
lpEnvironment: 一般设为NULL,
lpCurrentDirectory: 一般设为NULL
lpStartupInfo: 启动信息, 窗口显示信息等
lpProcessInformation: PROCESS_INFO指针获取新建进程的信息
lpCommandLine: 命令行,可执行文件的参数
lpProcessAttributes: 一般设为NULL
返回值:true成功,false失败
2. 创建进程示例
运行tree命令,前输出到d:\tree.txt:
BOOL MyCreateProcess()
{
STARTUPINFO si = {0};
si.cb = sizeof(si);
si.dwFlags |= STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; // 使用默认的IO句柄
si.wShowWindow = SW_HIDE; // 隐藏控制台窗口
PROCESS_INFORMATION pi = {0};
TCHAR cmdLine[100] = L"cmd.exe /c tree > d:\\tree.txt";
if (!CreateProcess(NULL, cmdLine, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi))
{
//cout << "创建进程失败!" << endl;
return FALSE;
}
// 线程不再被访问,关闭句柄,不影响句柄运行
CloseHandle(pi.hThread);
// 无限期等待线程执行完毕
// 主线程被挂起
WaitForSingleObject(pi.hProcess,INFINITE);
DWORD dwExitCode;
// 线程结束,获取返回码
GetExitCodeProcess(pi.hProcess,
&dwExitCode);
// 关闭线程句柄
CloseHandle(pi.hProcess);
return TRUE;
}
创建匿名管道,获取输出信息:
管道(Pipe)实际是用于进程间通信的一段共享内存,创建管道的进程称为管道服务器,连接到一个管道的进程为管道客户机。一个进程在向管道写入数据后,另一进程就可以从管道的另一端将其读取出来。匿名管道(Anonymous Pipes)是在父进程和子进程间单向传输数据的一种未命名的管道,只能在本地计算机中使用,而不可用于网络间的通信。
BOOL WINAPI CreatePipe(
_Out_ PHANDLE hReadPipe,
_Out_ PHANDLE hWritePipe,
_In_opt_ LPSECURITY_ATTRIBUTES lpPipeAttributes,
_In_ DWORD nSize
);
hReadPipe: 管道客户机句柄指针,用于读取数据
hWritePipe: 管道服务器句柄指针,用于写入数据
lpPipeAttributes: SECURITY_ATTRIBUTES数据结构的数据成员bInheritHandle设置为TRUE
nSize: 缓冲区大小, 0使用默认大小
返回值: 0失败,非0成功
示例:
BOOL MyCreateProcess()
{
SECURITY_ATTRIBUTES sa;
HANDLE hRead, hWrite;
std::string result;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
if (!CreatePipe(&hRead,&hWrite,&sa,0)) {
cout << "创建管道失败!" << endl;
return FALSE;
}
STARTUPINFO si = {0};
si.cb = sizeof(si);
si.dwFlags |= STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; // 使用默认的IO句柄
si.hStdOutput = hWrite;
si.hStdError = hWrite;
si.wShowWindow = SW_SHOWNORMAL; // 显示控制台窗口
PROCESS_INFORMATION pi = {0};
TCHAR cmdLine[256] = {0};
GetSystemDirectory(cmdLine, sizeof(cmdLine));
wcscat(cmdLine,L"\\cmd.exe");
TCHAR para[100] = L"cmd.exe /c tree";
if (!CreateProcess(NULL, para, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi))
{
cout << "创建进程失败!" << endl;
return FALSE;
}
// 线程不再被访问,关闭句柄,不影响句柄运行
CloseHandle(pi.hThread);
// 无限期等待线程执行完毕
// 主线程被挂起
WaitForSingleObject(pi.hProcess,INFINITE);
DWORD dwExitCode;
// 线程结束,获取返回码
GetExitCodeProcess(pi.hProcess,
&dwExitCode);
// 关闭线程句柄
CloseHandle(pi.hProcess);
CloseHandle(hWrite);
char buffer[257] = {0};
DWORD dwBytesRead;
while (ReadFile(hRead, buffer, 256, &dwBytesRead, NULL))
{
cout << buffer ;
memset(buffer, 0, 256);
}
CloseHandle(hRead);
return TRUE;
}
tastlist输出的内容会显示到控制台上。
同时定义读写双管道, 参考官网: Creating a Child Process with Redirected Input and Output