Reading output from the console

I need to read the output from an embedded C ++ console application in my C ++ /. NET. There are many articles about this, but most of them wait until the process is finished to read the result, which I don't want, I need to read it immediately after this process has finished "cout-ed" (and I don't want to block the GUI at the same time but this is something I can do myself). I tried two ways. One:

Diagnostics::Process ^process = gcnew Diagnostics::Process;
process->StartInfo->FileName = pathToExecutable;
process->StartInfo->RedirectStandardOutput = true;
process->StartInfo->UseShellExecute = false;
process->StartInfo->CreateNoWindow = true;
process->StartInfo->Arguments = "some params";
process->EnableRaisingEvents = true;
process->OutputDataReceived += gcnew Diagnostics::DataReceivedEventHandler( GUI::Form1::consoleHandler );
process->Start();
    process->BeginOutputReadLine();

      

And the handler:

    System::Void GUI::Form1::consoleHandler( System::Object^ sendingProcess, System::Diagnostics::DataReceivedEventArgs^ outLine ){
         GUI::Form1::contentForConsole += outLine->Data + "\n";
    }

      

But the debugger confirmed that it is only called after the process has finished.

On my second try, I tried to create a custom view flow:

Diagnostics::Process ^process = gcnew Diagnostics::Process;
process->StartInfo->FileName = pathToExecutable;
process->StartInfo->RedirectStandardOutput = true;
process->StartInfo->RedirectStandardError = true;
process->StartInfo->UseShellExecute = false;
process->StartInfo->CreateNoWindow = true;
process->StartInfo->Arguments = "some params";

    processStatic = process; // static class member

process->Start();

System::Windows::Forms::MethodInvoker^ invoker = gcnew System::Windows::Forms::MethodInvoker(reader);
invoker->BeginInvoke(nullptr, nullptr);

      

And the thread function, it waits for the ReadLine function until the process finishes:

System::Void GUI::Form1::reader(){
    System::String^ str;
    while ((str = geogenProcess->StandardOutput->ReadLine()) != nullptr)
    {
        contentForConsole += str; // timer invoked handler then displays this, but this line is called only once the process is finished
    }   
}

      

The executable process outputs many lines of text at intervals ranging from a few seconds to several minutes (depending on the specific task).

+2


source to share


2 answers


I managed to find the answer myself at the end. Both ways of reading console outputs work fine. The problem was in the console application. I didn't know that it was necessary to manually output the console output to make it available to other applications.

So after the replacement:

cout << "Some stuff " << some_var << " more stuff\n";

      



from

cout << "Some stuff " << some_var << " more stuff\n" << flush;

      

works like a charm.

+1


source


Why not redirect the called process' output to a file and read that file from your program? If the child process cleans up its exit well, you've gotten a pretty good reaction.



0


source







All Articles