Redirecting I / O from cmd.exe using CreateProcess () and CreatePipe()
First, the error of ERROR_BROKEN_PIPE(109) caused by the cmd.exe exit unexpectedly. According to the sample Creating a Child Process with Redirected Input and Output:
The parent process uses the opposite ends of these two pipes to write
to the child process's input and read from the child process's output.
As specified in the STARTUPINFO structure, these handles are also
inheritable. However, these handles must not be inherited. Therefore,
before creating the child process, the parent process uses the
SetHandleInformation function to ensure that the write handle for
the child process's standard input and the read handle for the child
process's standard output cannot be inherited.
You have set the other two handles to be un-inherited, so that cmd.exe exits without an available standard handle.
Set the pipe side of child process instead:
if (!SetHandleInformation(readFromCL, HANDLE_FLAG_INHERIT, 0)) {
cout << "SetHandleInformation error :: " << GetLastError() << endl;
}
if (!SetHandleInformation(writeToCL, HANDLE_FLAG_INHERIT, 0)) {
cout << "SetHandleInformation error :: " << GetLastError() << endl;
}
The issue of content size may because you need to wait for the output from cmd.exe. Add function like: Sleep(1000)
before ReadFile
Simply could solve it. Then, you could choose the most suitable method to synchronize the input and output of the two processes. Such as read in a for loop:
for (;;) {
memset(chBuff, '\0', deffBuffSize);
bSuccess = ReadFile(readFromCL, chBuff, deffBuffSize, &dRead, NULL);
if (!bSuccess || dRead == 0) {
break;
}
else {
cout << chBuff;
}
}
When outputting commands from cmd.exe (CreatProcess) I get More? Why and how to get rid of it?
The whole mistake was that I:
- Used "\0"
- WriteFile (writeToCL, outMes, sizeof (outMes) - 1, & dWrite, NULL)
wrote two characters "\0"
This program endlessly enters and receives information about ipconfig
The command line takes the command like this: [i][p][c][o][n][f][i][g][\n][\0]
char outMes[] = "ipconfig\n";
for (;;) {
if (WriteFile(writeToCL, outMes, sizeof(outMes) - 1, &dWrite, NULL) == FALSE) {
cout << GetLastError() << " :: error WriteFile" << endl;
return 1;
}
Sleep(2000);
memset(chBuff, '\0', deffBuffSize);
if (ReadFile(readFromCL, chBuff, deffBuffSize, &dRead, NULL) == FALSE) {
cout << "ReadFile error :: " << GetLastError() << endl;
return 1;
}
cout << chBuff;
}
P.S: Use strlen to determine the length of a string.
instead sizeof()
Cannot read pipe from CreateProcess() thread
The child process is dying as soon as it attempts to read from standard input, because:
if (!SetHandleInformation(cmd_in_rd, HANDLE_FLAG_INHERIT, 0)) {
This should have been:
if (!SetHandleInformation(cmd_in_wr, HANDLE_FLAG_INHERIT, 0)) {
like in the original code.
Also, your error handling is largely incorrect; you don't consistently check for errors and you sometimes call GetLastError() when no error has occurred. (Those problems are in the original code too.)
You also need to put the call to CloseHandle(cmd_out_wr);
back in because otherwise you won't be able to tell when the child exits.
Oh, and incidentally, cmd.exe
is a process, not a thread.
CreateProcess and capture stdout
The short answer is to create an anonymous pipe, setting the hStdOut
/hStdErr
and dwFlag
members of the STARTUPINFO
structure accordingly, and have CreateProcess()
inherit the handle for the writing end of the pipe. Don't forget to close your writing handle of your pipe, then you can read from the reading handle of the pipe in a loop until it fails with an ERROR_BROKEN_PIPE
error.
MSDN provides a detailed example of this:
Creating a Child Process with Redirected Input and Output
You are not the first person to do this, there should be plenty of example code and duplicate questions here on StackOverflow.
Related Topics
How to Return in Void Function
Printing Prime Numbers from 1 Through 100
Cancelling Boost Asio Deadline Timer Safely
I Want to Convert Std::String into a Const Wchar_T *
Uninitialized Pointers in Code
Cmake: Include Library Dependencies in a Static Library
What Is Data Alignment? Why and When Should I Be Worried When Typecasting Pointers in C
How to Identify the File Content as Ascii or Binary
How to Completely Disable Calls to Assert()
What Legitimate Reasons Exist to Overload the Unary Operator&
Unsigned and Signed Comparison
How to Read Files in Sequence from a Directory in Opencv
Use Channel Hiearchy of Boost.Log for Severity and Sink Filtering