CreateProcess and CreatePipe to execute a process and return output as a string in VC++

前端 未结 2 1563
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-30 17:19

I am trying to use CreateProcess and CreatePipe to execute a process from within a Windows Forms C++/CLR application in Visual Studio 2010.

相关标签:
2条回答
  • 2020-12-30 17:25

    Thanks to Hans Passant for the lead that got me to this clear and simple piece of code that does exactly what I was looking for.

    /// this namespace call is necessary for the rest of the code to work
    using namespace System::Diagnostics;
    using namespace System::Text;/// added for encoding
    
    Process^ myprocess = gcnew Process;
    Encoding^ Encoding;/// added for encoding
    Encoding->GetEncoding(GetOEMCP());/// added for encoding
    
    myprocess->StartInfo->FileName = "ping.exe";
    myprocess->StartInfo->Arguments = "127.0.0.1";
    myprocess->StartInfo->UseShellExecute = false;
    
    /// added the next line to keep a new window from opening
    myprocess->StartInfo->CreateNoWindow = true;
    
    myprocess->StartInfo->RedirectStandardOutput = true;
    myprocess->StartInfo->StandardOutputEncoding = Encoding;/// added for encoding
    myprocess->Start();
    
    String^ output = gcnew String( myprocess->StandardOutput->ReadToEnd() );
    
    myprocess->WaitForExit();
    
    /// OutputBox is the name of a Windows Forms text box in my app.
    OutputBox->Text = output;
    

    EDIT: Added encoding information. See above code.

    0 讨论(0)
  • 2020-12-30 17:42

    You are not making correct use of the ::ReadFile() function.

    Read about it here: http://msdn.microsoft.com/en-us/library/ms891445.aspx

    Basically, you want to fail with an error if the function ever does not return TRUE, and you want to keep looping until it yields a zero reDword.

    Also, ::ReadFile() will not zero-terminate your data for you, so you have to do it yourself, like this: buf[reDword] = '\0'; (make sure your buf is 101 chars long before doing that.)

    EDIT: Since I was asked to provide some example code, here it is, though I have not gone through the trouble of actually compiling it to make sure it works, so please beware of syntax errors, and generally consider it only as a rough pointer to the direction in which it should be done:

    #define BUFFER_SIZE 100
    string csoutput;
    for( ;; )
    {
        char buf[BUFFER_SIZE+1];
        DWORD redword; 
        if( !::ReadFile(rPipe,buf,BUFFER_SIZE,&redword,0) )
        {
            DWORD error = ::GetLastError();
            //throw new Exception( "Error " + error ); //or something similar
        }
        if( redword == 0 )
            break;
        buf[redword] = '\0';
        string cstemp = buf;
        csoutput += cstemp;
    }
    return csoutput;
    
    0 讨论(0)
提交回复
热议问题