CreateProcess()
和 CreatePipe()
是 Windows API 中的两个函数,用于创建新进程并与其进行通信。CreateProcess()
用于启动一个新进程,而 CreatePipe()
用于创建一个管道,以便在新进程和父进程之间传输数据。
PROCESS_INFORMATION
结构体,包含新进程的句柄等信息。以下是一个简单的示例,展示如何使用 CreateProcess()
和 CreatePipe()
从 cmd.exe
读取输出:
#include <windows.h>
#include <iostream>
int main() {
HANDLE hChildStdOutRead, hChildStdOutWrite;
SECURITY_ATTRIBUTES saAttr;
// Set the bInheritHandle flag so pipe handles are inherited.
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
// Create a pipe for the child process's STDOUT.
if (!CreatePipe(&hChildStdOutRead, &hChildStdOutWrite, &saAttr, 0)) {
std::cerr << "CreatePipe Error: " << GetLastError() << std::endl;
return 1;
}
// Ensure the read handle to the pipe for STDOUT is not inherited.
if (!SetHandleInformation(hChildStdOutRead, HANDLE_FLAG_INHERIT, 0)) {
std::cerr << "SetHandleInformation Error: " << GetLastError() << std::endl;
return 1;
}
// Create the child process.
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
BOOL bSuccess = FALSE;
// Set up members of the PROCESS_INFORMATION structure.
ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
// Set up members of the STARTUPINFO structure.
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdOutput = hChildStdOutWrite;
siStartInfo.hStdError = hChildStdOutWrite;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
// Create the child process.
bSuccess = CreateProcess(NULL,
"cmd.exe /c dir", // command line
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo); // receives PROCESS_INFORMATION
// If an error occurs, exit the application.
if (!bSuccess) {
std::cerr << "CreateProcess Error: " << GetLastError() << std::endl;
return 1;
}
// Close the write end of the pipe before reading from the read end of the pipe.
CloseHandle(hChildStdOutWrite);
// Read output from the child process's pipe for STDOUT.
CHAR chBuf[4096];
DWORD dwRead;
std::string strOutput;
while (ReadFile(hChildStdOutRead, chBuf, sizeof(chBuf), &dwRead, NULL) && dwRead != 0) {
strOutput.append(chBuf, dwRead);
}
// Close the read handle.
CloseHandle(hChildStdOutRead);
// Wait until child process exits.
WaitForSingleObject(piProcInfo.hProcess, INFINITE);
// Close process and thread handles.
CloseHandle(piProcInfo.hProcess);
CloseHandle(piProc::hThread);
// Output the result.
std::cout << "Output from cmd.exe:\n" << strOutput << std::endl;
return 0;
}
CreatePipe()
后调用 SetHandleInformation()
来防止读取句柄被继承。ReadFile()
读取管道数据时,可能会阻塞等待数据。可以使用超时参数或异步读取来解决。WaitForSingleObject()
等待子进程结束。通过以上步骤和示例代码,你可以实现从 cmd.exe
读取输出的功能。
领取专属 10元无门槛券
手把手带您无忧上云