После выполнения «systeminfo» commaind, waitforsinglebeject остановился

Так что, если вы запустите код ниже, он остановится на 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;
}

0

Решение

Хотя у меня не было проблем с запуском вашего кода, я подозреваю, что знаю проблему.

Скорее всего, вы зашли в тупик между процессом, пытающимся записать ваш дескриптор канала, и вашим кодом, ожидающим его завершения.

systeminfo записывает как минимум 2K данных в канал. Это может превысить буфер, встроенный в канал. Но ваша программа не читает из нее одновременно. Так что программа systeminfo не может выйти, потому что она застряла при записи в stdout. И ваша программа блокирует ожидание выхода приложения. Классический тупик. Программы, которые не выводят столько символов, работают нормально.

У меня нет времени для написания полного решения, но я полагаю, что вы захотите использовать цикл, который выполняет WaitForMultipleObjects как для дескриптора чтения, так и для дескриптора процесса. Если возможно, используйте неблокируемый или перекрывающийся ввод / вывод на ручке чтения.

Также измените ваш вызов ReadFile следующим образом:

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

Так что вы гарантировали нулевое завершение, когда весь буфер заполнен символами.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]