Posted By

jimfred on 06/21/10


Tagged

mfc CreateProcess


Versions (?)

Who likes this?

1 person have marked this snippet as a favorite

khouser


MFC, run command such as "ping 127.0.0.1" and get stdout in a CString.


 / Published in: C++
 

Do the equivalent of ShellExecute or the Win16-compatible WinExec: Run a command. But, get the command's stdout output in a CString.

  1. // Execute a command and get the results in a CString.
  2. // Synchronously launches a child process and waits up to 2 seconds for completion.
  3. // Uses a pipe to get the output of the child process.
  4. // Does not pipe to stdin of child process.
  5. // Example usage:
  6. // CString str;
  7. // str = ExecCmd( "ping 127.0.0.1 -n 99 " ); // This ping command will be terminated early before the -n 99 completes.
  8. // str.Replace( "\x0d\x0d\x0a", "\x0d\x0a" ); // fixes some ugly non-standard line terminators created by ping.
  9. //
  10. // str = ExecCmd( "java -version" ); // A more practical usage.
  11. //
  12. CString ExecCmd( LPCSTR pCmdArg)
  13. {
  14. // Handle Inheritance - to pipe child's stdout via pipes to parent, handles must be inherited.
  15. // SECURITY_ATTRIBUTES.bInheritHandle must be TRUE
  16. // CreateProcess parameter bInheritHandles must be TRUE;
  17. // STARTUPINFO.dwFlags must have STARTF_USESTDHANDLES set.
  18.  
  19. CString strResult; // Contains result of cmdArg.
  20.  
  21. HANDLE hChildStdoutRd; // Read-side, used in calls to ReadFile() to get child's stdout output.
  22. HANDLE hChildStdoutWr; // Write-side, given to child process using si struct.
  23.  
  24. BOOL fSuccess;
  25.  
  26. // Create security attributes to create pipe.
  27. SECURITY_ATTRIBUTES saAttr = {sizeof(SECURITY_ATTRIBUTES)} ;
  28. saAttr.bInheritHandle = TRUE; // Set the bInheritHandle flag so pipe handles are inherited by child process. Required.
  29. saAttr.lpSecurityDescriptor = NULL;
  30.  
  31. // Create a pipe to get results from child's stdout.
  32. // I'll create only 1 because I don't need to pipe to the child's stdin.
  33. if ( !CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0) )
  34. {
  35. return strResult;
  36. }
  37.  
  38. STARTUPINFO si = { sizeof(STARTUPINFO) }; // specifies startup parameters for child process.
  39.  
  40. si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; // STARTF_USESTDHANDLES is Required.
  41. si.hStdOutput = hChildStdoutWr; // Requires STARTF_USESTDHANDLES in dwFlags.
  42. si.hStdError = hChildStdoutWr; // Requires STARTF_USESTDHANDLES in dwFlags.
  43. // si.hStdInput remains null.
  44. si.wShowWindow = SW_HIDE; // Prevents cmd window from flashing. Requires STARTF_USESHOWWINDOW in dwFlags.
  45.  
  46. PROCESS_INFORMATION pi = { 0 };
  47.  
  48. // Create the child process.
  49. fSuccess = CreateProcess(
  50. NULL,
  51. (LPSTR)pCmdArg, // command line
  52. NULL, // process security attributes
  53. NULL, // primary thread security attributes
  54. TRUE, // TRUE=handles are inherited. Required.
  55. CREATE_NEW_CONSOLE, // creation flags
  56. NULL, // use parent's environment
  57. NULL, // use parent's current directory
  58. &si, // __in, STARTUPINFO pointer
  59. &pi); // __out, receives PROCESS_INFORMATION
  60.  
  61. if (! fSuccess)
  62. {
  63. return strResult;
  64. }
  65.  
  66. // Wait until child processes exit. Don't wait forever.
  67. WaitForSingleObject( pi.hProcess, 2000 );
  68. TerminateProcess( pi.hProcess, 0 ); // Kill process if it is still running. Tested using cmd "ping blah -n 99"
  69.  
  70. // Close the write end of the pipe before reading from the read end of the pipe.
  71. if (!CloseHandle(hChildStdoutWr))
  72. {
  73. return strResult;
  74. }
  75.  
  76. // Read output from the child process.
  77. for (;;)
  78. {
  79. DWORD dwRead;
  80. CHAR chBuf[4096];
  81.  
  82. // Read from pipe that is the standard output for child process.
  83. bool done = !ReadFile( hChildStdoutRd, chBuf, 4096, &dwRead, NULL) || dwRead == 0;
  84. if( done )
  85. {
  86. break;
  87. }
  88.  
  89. // Append result to string.
  90. strResult += CString( chBuf, dwRead) ;
  91. }
  92.  
  93. // Close process and thread handles.
  94. CloseHandle( hChildStdoutRd );
  95.  
  96. // CreateProcess docs specify that these must be closed.
  97. CloseHandle( pi.hProcess );
  98. CloseHandle( pi.hThread );
  99.  
  100. return strResult;
  101. }

Report this snippet  

You need to login to post a comment.