I started a Visual C++ Desktop Application (win32) and created a button, that creates a process.
Here is the button code:
INT_PTR CALLBACK Btn_Click(HWND hWnd)
{
wchar_t cmd[] = L"cmd.exe /c testprogram.exe";
STARTUPINFOW startInf;
memset(&startInf, 0, sizeof startInf);
PROCESS_INFORMATION procInf;
memset(&procInf, 0, sizeof procInf);
BOOL p = CreateProcess(NULL, cmd, NULL, NULL, TRUE,
CREATE_NO_WINDOW, NULL, NULL, &startInf, &procInf);
if (p)
{
CloseHandle(procInf.hProcess);
CloseHandle(procInf.hThread);
}
return TRUE;
}
I want to read the process's stdout output (cmd.exe or testprogram.exe) while it is 'running' and set it as a string. After setting the content of a created Text input.
I tried this answer, but it freezes the application. (because of ReadFile() and while() loop)
How to read output from cmd.exe using CreateProcess() and CreatePipe()
I searched the forum for a better answer, but every example is for a console app.
Update: I can read the output of ping.exe but the window stays frozen until ping.exe closes. the for() loop (and ReadFile()) blocks the window .
wchar_t command[] = L"ping localhost";
STARTUPINFOW startInf;
memset(&startInf, 0, sizeof startInf);
PROCESS_INFORMATION procInf;
memset(&procInf, 0, sizeof procInf);
HANDLE cout_r = NULL;
HANDLE cout_w = NULL;
SECURITY_ATTRIBUTES sec_a;
//memset(&sec_a, 1, sizeof sec_a);
sec_a.nLength = sizeof(SECURITY_ATTRIBUTES);
sec_a.lpSecurityDescriptor = NULL;
CreatePipe(&cout_r, &cout_w, &sec_a, 0);
SetHandleInformation(cout_r, HANDLE_FLAG_INHERIT, 0);
//startInf.cb = sizeof(STARTUPINFO);
startInf.hStdOutput = cout_w;
startInf.dwFlags |= STARTF_USESTDHANDLES;
BOOL p = CreateProcess(NULL, command, NULL, NULL, TRUE,
NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, NULL, NULL,
&startInf, &procInf);
if (p)
{
CloseHandle(procInf.hProcess);
CloseHandle(procInf.hThread);
CloseHandle(cout_w);
}
else
{
SetWindowTextA(hedit, "Failed");
}
char buf[1024];
CHAR chBuf[4096];
DWORD dwRead;
for (;;)
{
BOOL bSuccess = ReadFile(cout_r, chBuf, 4096, &dwRead, NULL);
if (!bSuccess || dwRead == 0) break;
std::string s(chBuf, dwRead);
std::wstring stemp = std::wstring(s.begin(), s.end());
OutputDebugStringW(stemp.c_str());
}
I searched for asynchronous I/O on ReadFile and pipes. If anyone can provide me an example on how to do async Readfile without for() loop would be good.