exe not reporting on stdout - but working through bat file

111 Views Asked by At

When I run an exe file through a bat file as intermediary for stdin and stdout pipes then it works, but not when I run it directly

I have an exe file: p.exe. It is supposed to receive input on stdin and then output on stdout. If I run it manually and input: "hello" then it responds "help".

If I run it through createProcessA and give it "hello\n" through WriteFile, then I can see it working (processmonitor), but I do not get any output on stdOut or stdErr.

Therefore, I created a batscript as intermediary:

@echo off
    setlocal
    
    :input_loop
        set /p UserInput=
    
        :: Check if the input is 'exit' to break the loop
        if "%UserInput%"=="exit" goto end_loop
    
        :: Pass the input to p.exe and display the output
        echo %UserInput% | %~dp0p.exe
    
        :: Go back to the start of the loop
        goto input_loop
    
    :end_loop
    endlocal

and then I can run this batscript through createProcessA, and it works!

Here is my test:

    TEST_METHOD(SO_TEST) {
        std::string path = "test.bat";
        HANDLE hStdInPipeWrite;
        HANDLE hStdOutPipeRead;
        SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
        HANDLE hStdInPipeRead = NULL;
        HANDLE hStdOutPipeWrite = NULL;
    
        // Create two pipes
        //hStdInPipeRead is the read end of the pipe for the child process. hstdinPipeWrite is the write end of the pipe for the parent process.
        //hstdoutPipeRead is the read end of the pipe for the parent process. hstdoutPipeWrite is the write end of the pipe for the child process.
    
        if (!CreatePipe(&hStdInPipeRead, &hStdInPipeWrite, &sa, 0) ||
            !CreatePipe(&hStdOutPipeRead, &hStdOutPipeWrite, &sa, 0)) {
            abort();
        }
    
        SetHandleInformation(hStdInPipeWrite, HANDLE_FLAG_INHERIT, 0);
    
        SetHandleInformation(hStdOutPipeRead, HANDLE_FLAG_INHERIT, 0);
    
    
        STARTUPINFOA si = {};
        si.cb = sizeof(STARTUPINFO);
        si.dwFlags |= STARTF_USESTDHANDLES;
        si.hStdError = hStdOutPipeWrite;
        si.hStdOutput = hStdOutPipeWrite;
        si.hStdInput = hStdInPipeRead;
    
        std::string directory = path.substr(0, path.find_last_of("\\"));
        std::string fileName = path.substr(path.find_last_of("/\\") + 1);
        PROCESS_INFORMATION pi = {};
        if (!CreateProcessA(NULL, const_cast<char*>(path.c_str()), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
            DWORD lastError = GetLastError();
            abort();
        }
    
        // Close pipes as they belong to the child
        CloseHandle(hStdOutPipeWrite);
        CloseHandle(hStdInPipeRead);
        std::string data = "hello";
        DWORD dwWritten;
        bool result = WriteFile(hStdInPipeWrite, data.c_str(), data.length(), &dwWritten, NULL);
    
        char buf[1024 + 1];
        DWORD dwRead;
        if (ReadFile(hStdOutPipeRead, buf, 1024, &dwRead, NULL)) {
            buf[dwRead] = '\0';
        }
    
        //buf contains "help\r\n"
    }

but if I change test.bat to p.exe, then I do not get any output.

I have also tried using https://gitlab.com/eidheim/tiny-process-library with the same result.

I am guessing that it has something to do with the environment, but I do not know what.

0

There are 0 best solutions below