C++ 读取 Java 进程输出

c++ read java process output

本文关键字:输出 进程 Java 读取 C++      更新时间:2023-10-16

我有一个运行java进程并读取其输出的C++程序。我使用了以下 MSDN 代码:

http://msdn.microsoft.com/en-us/library/ms682499%28v=vs.85%29.aspx

但是,当读取输出的最后一行时

bSuccess = ReadFile(g_hInputFile, chBuf, BUFSIZE, &dwRead, NULL);

bsucces等于 1,所以程序继续到下一个循环,当到达同一行时,程序只是"飞",无一例外,停止调试,断点永远不会移动到下一行。

我想这是因为没有EOF指示停止阅读。但是,java没有EOF字符。Java程序只是:

System.out.close();

最后。

我可以在C++\Java代码中做什么来修复它?

编辑:

这是代码。

它不适用于任何控制台应用程序,读取到结束然后"挂起"。

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();
            ...
}

这个问题似乎在您链接的页面的某些评论中得到解决:您必须在创建子进程后关闭管道的写入侧,但在从另一侧开始读取之前。如果不这样做,即使子进程关闭其输出,管道的写入端仍会打开(由父进程打开),因此永远不会达到 EOF。

啊,不要忘记关闭父进程的所有句柄。链接页面中的示例没有,并且泄漏!