I have an exe program in Windows which in the terminal works as follows
> program.exe parameter01 file
entry01 (user types entry01)
output01
entry02 (user types entry02)
output02
...
until the combination Ctrl+D is pressed.
I need to create a "child process" in a C language which is capable to run the program and sent entries to the "child process" and receive the output in a char[] or string.
I know I have to use the CreateProcess method but I don't know how to pass an entry like an input and retrieve the output, How can I do this?
I have seen this using Java but I need to implement this functionality in C language.
Use the STARTUPINFO
structure
You must set the attribute hStdInput
.
More and less, this is what you need (it is C++ code and it may not compile, but you'll get the idea):
std::string GetProcessOutput(HANDLE hStdOutProcess) {
std::stringstream strStream;
char lpBuffer[2] = {0};
DWORD nBytesRead;
while(true){
BOOL bResult = ReadFile(hStdOutProcess, lpBuffer, sizeof(char), &nBytesRead, NULL);
if (bResult && nBytesRead) {
strStream << lpBuffer;
} else {
break;
}
}
return strStream.str();
}
void RunAndGetOutout() {
HANDLE hProcessStdOutRead = NULL;
HANDLE hProcessStdOutWrite = NULL;
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE; // allow to inherit handles from parent process
saAttr.lpSecurityDescriptor = NULL;
if(!CreatePipe(&hProcessStdOutRead, &hProcessStdOutWrite, &saAttr, 0)) {
return nResult;
}
if(!SetHandleInformation(hProcessStdOutRead, HANDLE_FLAG_INHERIT, 0)) {
return nResult;
}
STARTUPINFO startInfo;
PROCESS_INFORMATION processInfo;
char cmdLine[ MAX_PATH*2 +40] = {0};
char currentDir[MAX_PATH] = {0};
ZeroMemory(&startInfo, sizeof(startInfo));
startInfo.cb = sizeof(startInfo);
startInfo.hStdOutput = hProcessStdOutWrite; // set the handle
startInfo.dwFlags |= STARTF_USESTDHANDLES; // attention with this one
ZeroMemory(&processInfo, sizeof(processInfo));
GetCurrentDirectory(MAX_PATH, currentDir);
sprintf(cmdLine, "\"%s\" %s", (const char*)m_path2Process, (const char*)m_processArgs);
if(CreateProcess( NULL, cmdLine, NULL, NULL, TRUE, 0, NULL, currentDir, &startInfo, &processInfo)) {
cout << GetProcessOutput(hProcessStdOutRead) << endl;
CloseHandle(processInfo.hThread);
CloseHandle(processInfo.hProcess);
}
CloseHandle(hProcessStdOutRead);
CloseHandle(hProcessStdOutWrite)
}