2017-04-14 4 views
0

したがって、以下のコードを実行すると、int retVal = WaitForSingleObject(processInfo.hProcess, INFINITE);に永遠に停止します。しかし、 "systeminfo"の代わりに "ipconfig"や "ping 192.168.0.1"を実行すると、コードは完全に動作します。私はこの問題を解決する方法を知りたいのですが、その原因は何ですか?"systeminfo"コマンドを実行した後、waitforsingleオブジェクトが停止しました

#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呼び出しを変更します。あなたはバッファ全体を文字で埋められるヌル終了を保証することを

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

ような。

+0

あなたが言ったことは私にとって意味があり、私のプログラムでは何が問題か分かりました。しかし、コンパイラで動かないうちに、同じコードをどのように実行したのですか?そして、私はまだ解決策を理解することができません。私は、systeminfoプログラムが完全に終了した後にReadFileしたいです。 –

+0

あなたはまったく正しいです、私のコンピュータのパイプ書き込みバフは4kbです。どういうわけか私はそれがあなたのコンピュータ上で完璧に動作する理由thats 64kbだと思う。私はパイプの代わりにファイルリダイレクト出力を使用しました。私は今すぐ出力を得ることができますが、私はまだ何かのソリューションをコンソールに入力しますか? –

関連する問題