2017-04-14 5 views
0

따라서 아래 코드를 실행하면 int retVal = WaitForSingleObject(processInfo.hProcess, INFINITE);에 영원히 멈출 것입니다. 하지만 "ipconfig"또는 "ping 192.168.0.1"대신 "systeminfo"를 실행하면 코드가 완벽하게 작동합니다. 문제를 해결하는 방법을 알고 싶습니다. 이유는 무엇입니까?"systeminfo"commaind를 실행 한 후 waitforsingleobject가 중지되었습니다

#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; 
} 

답변

0

코드를 실행하는 데 문제가 없었지만 문제가 있음을 알고 있습니다.

파이프 핸들에 쓰려고하는 프로세스와 종료 할 때까지 기다리는 코드 사이에 교착 상태가 발생할 수 있습니다.

systeminfo 적어도 2K 상당의 데이터를 파이프에 씁니다. 파이프에 내장 된 버퍼를 초과 할 수 있습니다. 그러나 귀하의 프로그램은 동시에 그것을 읽지 않습니다. 따라서 systeminfo 프로그램은 stdout에 쓰여져 있기 때문에 종료 할 수 없습니다. 그리고 프로그램이 종료 될 때까지 기다리는 것을 차단합니다. 고전적인 교착 상태. 많은 문자를 출력하지 않는 프로그램은 정상적으로 작동합니다.

완벽한 솔루션을 코딩 할 시간이 없지만 읽기 핸들과 프로세스 핸들 모두 WaitForMultipleObjects를 수행하는 루프를 사용하고 싶습니다. 가능한 경우 읽기 핸들에서 비 차단 또는 겹쳐진 I/O를 사용하십시오. 다음과 같이

또한, 귀하의 ReadFile을 호출을 수정하면 전체 버퍼가 문자로 가득 차있다 널 (null) 종료를 보장하는 것이

DWORD dwResult = ReadFile(hRead,buffer,sizeof(buffer)-1,&bytesRead,NULL); 
if (dwResult > 0) 
{ 
    buffer[dwResult] = '\0'; 
} 

같은.

+0

당신이 말한 것은 나에게 의미가 있으며, 나는 내 프로그램에서 어떤 문제인지 이해하고 있습니다. 하지만 컴파일러에서 작동하지 않는 동안 동일한 코드가 어떻게 실행됩니까? 그리고 저는 여전히 그 해결책을 이해할 수 없습니다. systeminfo 프로그램이 완전히 종료 된 후 ReadFile을 원합니다. –

+0

당신은 내 컴퓨터에 4 킬로바이트 파이프를 쓰는 것이 합당합니다. 어쨌든 나는 그것이 당신의 컴퓨터에서 완벽하게 작동하는 이유는 64kb라고 생각합니다. 파이프 대신 파일 리디렉션 출력을 사용했습니다. 이제 출력을 성공적으로 가져올 수 있지만 여전히 모든 솔루션을 콘솔에 입력 할 수 있습니까? –