使用CreateProcess创建一个运行sfc.exe的进程。但是,没有效果。我有运行此程序的管理员权限
使用CreateProcess接口控制CUI的输出,捕获CUI程序的输出信息。
我想使用管道和/scannow来接收sfc命令输出。
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
HANDLE hReadPipe = NULL;
HANDLE hWirtePipe = NULL;
if (!CreatePipe(&hReadPipe, &hWirtePipe, &sa, NULL)) {
std::cout << "create pipe failed \n";
return -1;
}
PROCESS_INFORMATION pi;
STARTUPINFO si;
ZeroMemory(&si, sizeof(STARTUPINFO));
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES,
si.wShowWindow = SW_HIDE;
si.hStdError = hWirtePipe;
si.hStdOutput = hWirtePipe;
TCHAR szCommand[] = TEXT("sfc /scannow");
if (!CreateProcess(NULL, szCommand, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
{
cout << "process create failed ,errno is :"<< GetLastError() << endl;
CloseHandle(hReadPipe);
CloseHandle(hWirtePipe);
return -1;
}
DWORD dwRead = 0;
DWORD stdRead = 0;
DWORD total;
DWORD timeout = 50;
TCHAR bufferOutPipe[1024] = {0};
TCHAR readBuffer[1024] = {0};
BOOL flag = true;
while (flag) {
if (WAIT_TIMEOUT == WaitForSingleObject(pi.hProcess, timeout)) {
if (!PeekNamedPipe(hReadPipe, bufferOutPipe, 1024, &dwRead, &total, 0) || dwRead <= 0) {
continue;
}
else {
ReadFile(hReadPipe, readBuffer, dwRead, &stdRead, NULL);
printf("%s\n", readBuffer);
dwRead = 0;
}
}
else if (WAIT_OBJECT_0 == WaitForSingleObject(pi.hProcess, timeout)) {
if (PeekNamedPipe(hReadPipe, bufferOutPipe, 1024, &dwRead, &total, 0) && dwRead > 0) {
ReadFile(hReadPipe, readBuffer, dwRead, &stdRead, NULL);
printf("%s\n", readBuffer);
}
flag = false;
}
ZeroMemory(readBuffer, 1024);
}
CloseHandle(hReadPipe);
CloseHandle(hWirtePipe);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
我想接收SFC/scannow命令的输出,并使用匿名管道和进程重定向输出,但我听不到任何管道数据,创建的进程立即启动。
我以管理员身份启动了visual studio。
发布于 2021-03-31 18:58:59
si.hStdInput
未初始化为有效值。0无效。你似乎想要INVALID_HANDLE_VALUE
。
使用bInheritHandles
的FALSE
,您的输出重定向无论如何都不会起作用。这似乎是您当前的根本问题。
此外,一旦进程打开,您的代码将永远旋转,因为CloseHandle(hWirtePipe);
不是及时调用的,而是在循环之后调用的。然后处理你的把手漏水的问题。
现在进入等待循环。糟透了。正常的构造是一直读到管道的末尾,然后才等待进程退出。当循环停止时,您有一个竞争条件,这将导致您(最有可能)丢失输出的尾部。请注意,这将永远阻塞,直到您在进入循环之前关闭写入结束的副本。你也不需要任何PeekWhatever的废话。只需ReadFile句柄,直到得到管道末端的特定错误。
https://stackoverflow.com/questions/66885369
复制相似问题