执行“systeminfo”命令后,waitforsingleobject停止

时间:2017-04-14 22:35:03

标签: c++ createprocess waitforsingleobject

因此,如果您运行下面的代码,它将永远停留在int retVal = WaitForSingleObject( processInfo.hProcess, INFINITE);。但是当我运行“ipconfig”或“ping 192.168.0.1”而不是“systeminfo”时,代码运行完美。我想知道如何解决问题,导致这个问题的原因是什么?

#include <windows.h>

int WINAPI WinMain(
                   HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpComLine,
                   int nCmdShow)
{
    SECURITY_ATTRIBUTES secAttr; 
    HANDLE hRead,hWrite;

secAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
secAttr.lpSecurityDescriptor = NULL; 
secAttr.bInheritHandle = TRUE; 
if (!CreatePipe(&hRead,&hWrite,&secAttr,0)) 
{ 
    return FALSE; 
} 

char command[1024];
strcpy(command, "systeminfo");

STARTUPINFO startupInfo;
PROCESS_INFORMATION processInfo; 
startupInfo.cb = sizeof(STARTUPINFO); 
GetStartupInfo(&startupInfo); 
startupInfo.hStdError = hWrite;  
startupInfo.hStdOutput = hWrite;    
startupInfo.hStdInput = hRead;      
startupInfo.lpTitle = "CMD";
startupInfo.wShowWindow = SW_HIDE; 
startupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
if (!CreateProcess(NULL, command,NULL,NULL,TRUE,NULL,NULL,NULL,&startupInfo,&processInfo)) 
{ 
    MessageBox(NULL, "Error", NULL, MB_OK);
    CloseHandle(hWrite); 
    CloseHandle(hRead); 
    return FALSE; 
} 

char buffer[1024] = {0};         
DWORD bytesRead; 

int retVal = WaitForSingleObject( processInfo.hProcess, INFINITE);
if (retVal == WAIT_FAILED)
    MessageBox(NULL, "WAIT_FAILED", NULL, MB_OK);
else if (retVal == WAIT_TIMEOUT)
    MessageBox(NULL, "WAIT_TIMEOUT", NULL, MB_OK);
ReadFile(hRead,buffer,1024,&bytesRead,NULL);
MessageBox(NULL, buffer, NULL, MB_OK);

CloseHandle(hWrite); 
CloseHandle(hRead);

return 0;
}

1 个答案:

答案 0 :(得分:0)

虽然我在运行代码时没有遇到任何问题,但我怀疑我知道这个问题。

您可能在尝试写入管道句柄的进程和等待它退出的代码之间陷入僵局。

Pred FAILCODE TEST向管道写出至少2K的数据。这可能会超过管道中内置的缓冲区。但是你的程序不能同时读取它。所以systeminfo程序无法退出,因为它写入了stdout。并且您的程序会阻止等待应用程序退出。经典的僵局。不输出多个字符的程序可以正常工作。

我没有时间编写完整的解决方案,但我相信你会想要使用一个循环来为read句柄和进程句柄执行WaitForMultipleObjects。如果可能,请在Read句柄上使用非阻塞或重叠i / o。

另外,修改您的ReadFile调用,如下所示:

systeminfo

这样可以在整个缓冲区填充字符时保证空终止。