title: CreateProcess and CreatePipe to execute a process and return output as a string in VC++
body: <p>I am trying to use <code>CreateProcess</code> and <code>CreatePipe</code> to execute a process from within a Windows Forms C++/CLR application in Visual Studio 2010.</p>
  
  <p>From within my Windows forms app I want to execute a child process (console app) and return the output as a <code>std::string</code>, <code>std::wstring</code>, or <code>System::String^</code> within my Windows forms app. Additionally, I do not want the newly created child process to spawn a window.</p>
  
  <p>The console application is of my own creation, so I have control of it's source too.</p>
  
  <p>I have seen the following examples, but I do not understand how to modify the code to accomplish what I am trying to do:</p>
  
  <ul>
  <li><a href="http://msdn.microsoft.com/en-us/library/ms682499(VS.85).aspx" rel="nofollow noreferrer">MSDN</a></li>
  <li><a href="http://code.google.com/p/kgui/source/browse/trunk/kguithread.cpp" rel="nofollow noreferrer">kgui</a></li>
  <li><a href="http://www.codeproject.com/KB/cpp/9505Yamaha_1.aspx" rel="nofollow noreferrer">A simpler MFC based function</a></li>
  </ul>
  
  <p>The MSDN code appears to be written as two console apps, one calling the other. The code is confusing to me. I've only been working in C++ for about 4 months, so I still don't understand everything. It appears to reference a text file, which I don't need to do.</p>
  
  <p>Is there a simpler way to do this than MSDN's 200+ lines of code or kgui's 300+ lines of code?</p>
  
  <p>The answer <a href="https://stackoverflow.com/questions/1184433/execute-a-process-and-return-its-standard-output-in-vc">here</a> was helpful, but over simplistic. I was hoping to see a basic source example (one that doesn't involve hundreds of lines of complex code would be preferable). I would have used the MFC code, but I had difficulty adapting it to my purposes (I'm not using MFC).</p>
  
  <p>Following is my adaptation of the code from Code Project:</p>
  
  <pre><code>string ExecuteExternalFile(string csExeName, string csArguments)
  {
    string csExecute;
    csExecute=csExeName + " " + csArguments;
  
    SECURITY_ATTRIBUTES secattr; 
    ZeroMemory(&amp;secattr,sizeof(secattr));
    secattr.nLength = sizeof(secattr);
    secattr.bInheritHandle = TRUE;
  
    HANDLE rPipe, wPipe;
  
    //Create pipes to write and read data
  
    CreatePipe(&amp;rPipe,&amp;wPipe,&amp;secattr,0);
    //
  
    STARTUPINFO sInfo; 
    ZeroMemory(&amp;sInfo,sizeof(sInfo));
    PROCESS_INFORMATION pInfo; 
    ZeroMemory(&amp;pInfo,sizeof(pInfo));
    sInfo.cb=sizeof(sInfo);
    sInfo.dwFlags=STARTF_USESTDHANDLES;
    sInfo.hStdInput=NULL; 
    sInfo.hStdOutput=wPipe; 
    sInfo.hStdError=wPipe;
  
    //Create the process here.
  
    CreateProcess(0,(LPWSTR)csExecute.c_str(),0,0,TRUE,NORMAL_PRIORITY_CLASS|CREATE_NO_WINDOW,0,0,&amp;sInfo,&amp;pInfo);
    CloseHandle(wPipe);
  
    //now read the output pipe here.
  
    char buf[100];
    DWORD reDword; 
    string m_csOutput,csTemp;
    BOOL res;
    do
    {
                    res=::ReadFile(rPipe,buf,100,&amp;reDword,0);
                    csTemp=buf;
                    m_csOutput+=csTemp;
    }while(res);
    return m_csOutput;
  }
  </code></pre>
  
  <p>I have tried using this from within my Windows Forms app, and while it compiles ok and doesn't cause any errors, it doesn't seem to work either. I have no idea why.</p>
  
  <p>This is how I executed the above code:</p>
  
  <pre><code>std::string ping = ExecuteExternalFile("ping.exe", "127.0.0.1");
  </code></pre>
  
  <p>It did not appear to do anything, except that on the first execution it give a very strange 3 characters as an output, then on subsequent executions, nothing.</p>