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

I am trying to use CreateProcessand CreatePipeto execute a process from a Windows Forms C ++ / CLR application in Visual Studio 2010.

In my Windows forms application, I want to execute a child process (console application) and return the result in the form std::string, std::wstringor System::String^in my Windows forms application. In addition, I do not want the newly created child process to spawn a window.

The console application has my own creation, so I also control its source.

I saw the following examples, but I don’t understand how to change the code to accomplish what I am trying to do:

MSDN code appears as two console applications, one of which calls the other. The code confuses me. I have been working only in C ++ for about 4 months, so I still don't understand everything. It seems to be referencing a text file that I don't need to do.

Is there an easier way to do this than an MSDN of 200+ lines of code or a kilobyte of more than 300 lines of code?

The answer here was useful, but more simplified. I was hoping to see an example of a basic source (one that doesn't include hundreds of lines of complex code would be preferable). I would use the MFC code, but it was difficult for me to adapt it to my goals (I do not use MFC).

Following is my adaptation of the code from Code Project:

string ExecuteExternalFile(string csExeName, string csArguments)
{
  string csExecute;
  csExecute=csExeName + " " + csArguments;

  SECURITY_ATTRIBUTES secattr; 
  ZeroMemory(&secattr,sizeof(secattr));
  secattr.nLength = sizeof(secattr);
  secattr.bInheritHandle = TRUE;

  HANDLE rPipe, wPipe;

  //Create pipes to write and read data

  CreatePipe(&rPipe,&wPipe,&secattr,0);
  //

  STARTUPINFO sInfo; 
  ZeroMemory(&sInfo,sizeof(sInfo));
  PROCESS_INFORMATION pInfo; 
  ZeroMemory(&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,&sInfo,&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,&reDword,0);
                  csTemp=buf;
                  m_csOutput+=csTemp;
  }while(res);
  return m_csOutput;
}

Windows Forms, , , . , .

:

std::string ping = ExecuteExternalFile("ping.exe", "127.0.0.1");

, , 3 , .

+2
2

Hans Passant lead, , , .

/// 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: ​​ . . .

+2

::ReadFile().

: http://msdn.microsoft.com/en-us/library/ms891445.aspx

, , TRUE, , reDword.

, ::ReadFile() , , : buf[reDword] = '\0'; (, buf 101 .)

EDIT: - , , , , , , , , :

#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;
+3

All Articles