2

I need to read output from native C++ console application in my C++/.NET. There are many articles about this, but most wait until the process ends to read the output, which I don't want to, I need to read it immediately after it is "cout-ed" by the process (and don't want to block the GUI while doing so, but that's something I can do on my own). 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 debugger confirmed it is called only after the process is finished.

On my second attempt I tried to create custom watching thread:

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 on 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 process executable ouputs many lines of text over time span ranging from several seconds to several minutes (depending on the actual task).

1
  • I'm interested in this too; we have a similar problem in our shop, though not in a critical location. Commented Oct 15, 2009 at 19:41

2 Answers 2

1

I managed to find the answer myself in the end. Both ways of reading console output are perfectly functional. The problem was in the console application. I didn't know it is necessary to flush the console output manually to make it available to other apps.

So after replacing:

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

with

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

works like charm.

Sign up to request clarification or add additional context in comments.

Comments

0

Why don't redirect called process' output to a file and read that file from your program? If the child process flushes its output well, then you got a quite good response.

1 Comment

The output file was written after the process finished as well.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.