0

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.

5
  • See Creating a Child Process with Redirected Input and Output on MSDN. Commented May 15, 2021 at 22:11
  • I tried this example but it stops the Main window at ReadFile(), if bInheritHandles=TRUE and if it's FALSE, it doesn't read the stdout output. Commented May 16, 2021 at 9:33
  • use asynchronous I/O on pipes. Commented May 16, 2021 at 12:40
  • @RbMm I searched for asynchronous I/O on ReadFile and pipes, none of them worked. I updated the question on how far I have reached. Commented May 16, 2021 at 16:09
  • CreatePipe create synchronous file handle. you need not use this api. use ZwCreateNamedPipeFile or CreateNamedPipeW for begin Commented May 16, 2021 at 16:17

1 Answer 1

2

If your UI thread stops pumping messages Windows treats it as frozen. This means you should not perform blocking I/O on this thread.

You could use asynchronous (overlapped) I/O with ReadFile but doing the whole child process operation in another thread is a lot easier. The button press would start the thread and once the thread has read stdout it can signal back to your main window by sending a WM_APP message.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.