I have a C++ program that runs a java process and reads it's output. I used the following MSDN code:
http://msdn.microsoft.com/en-us/library/ms682499%28v=vs.85%29.aspx
However, when reading the final line of the output
bSuccess = ReadFile(g_hInputFile, chBuf, BUFSIZE, &dwRead, NULL);
bsucces equals 1, so the program continue to the next loop, and when reaching the same line, the program just "fly", with no exception, stopping to debug, the breakpoint never moves to then next line.
I guess this is because there is no EOF to indicate stop reading. However, java do not have a EOF charcater. The java program simply does:
System.out.close();
at end.
What can I do in the C++\Java code in order to fix it?
EDIT:
Here is the code.
It doesn't work with any console application, read to end and then "hang".
HANDLE g_hChildStd_IN_Rd = NULL;
HANDLE g_hChildStd_IN_Wr = NULL;
HANDLE g_hChildStd_OUT_Rd = NULL;
HANDLE g_hChildStd_OUT_Wr = NULL;
HANDLE g_hInputFile = NULL;
PROCESS_INFORMATION piProcInfo;
void CreateChildProcess()
// Create a child process that uses the previously created pipes for STDIN and STDOUT.
{
std::string d=processLoaction;
TCHAR *cmdline=new TCHAR[d.size()+1];
cmdline[d.size()]=0;
std::copy(d.begin(),d.end(),cmdline);
STARTUPINFO siStartInfo;
BOOL bSuccess = FALSE;
// Set up members of the PROCESS_INFORMATION structure.
ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
// Set up members of the STARTUPINFO structure.
// This structure specifies the STDIN and STDOUT handles for redirection.
ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdError = g_hChildStd_OUT_Wr;
siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
// Create the child process.
bSuccess = CreateProcess(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &siStartInfo, &piProcInfo); // receives PROCESS_INFORMATION
// If an error occurs, exit the application.
if ( ! bSuccess )
throw new Exception("Failed to create process");
else
{
// Close handles to the child process and its primary thread.
// Some applications might keep these handles to monitor the status
// of the child process, for example.
CloseHandle(piProcInfo.hProcess);
CloseHandle(piProcInfo.hThread);
}
}
void ReadFromPipe(void)
// Read output from the child process's pipe for STDOUT
// and write to the parent process's pipe for STDOUT.
// Stop when there is no more data.
{
DWORD dwRead, dwWritten,status;
CHAR chBuf[BUFSIZE];
BOOL bSuccess = FALSE;
HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
BOOL res;
for (;;)
{
bSuccess = ReadFile( g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL);
if( ! bSuccess || dwRead == 0 )
break;
chBuf[dwRead] = NULL;
bSuccess = WriteFile(hParentStdOut, chBuf, dwRead, &dwWritten, NULL);
if (! bSuccess )
break;
}
}
int main(int argc, char** argv)
{
//run the Jar to validate manifest & jeff
SECURITY_ATTRIBUTES saAttr;
// Set the bInheritHandle flag so pipe handles are inherited.
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
// Create a pipe for the child process's STDOUT.
if ( ! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0) )
throw new Exception("faild to create a pipe for the child process's STDOUT");
// Ensure the read handle to the pipe for STDOUT is not inherited.
if ( ! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) )
throw new Exception("Read handle to the pipe for STDOUT is inherited");
CreateChildProcess();
ReadFromPipe();
...
}
bSuccess = ReadFile( g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL);.