【问题标题】:Reading output from console program从控制台程序读取输出
【发布时间】:2023-03-21 10:44:01
【问题描述】:

我需要在我的 C++/.NET 中读取本机 C++ 控制台应用程序的输出。有很多关于这个的文章,但大多数等到进程结束才读取输出,我不想,我需要在进程“cout-ed”之后立即阅读它(并且不想要这样做时阻止 GUI,但这是我可以自己做的事情)。我尝试了两种方法。一:

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();

还有处理程序:

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

但调试器确认只有在进程完成后才会调用它。

第二次尝试创建自定义观看线程:

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);

还有线程函数,它在ReadLine函数上等待,直到进程完成:

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
    }   
}

进程可执行文件输出多行文本,时间跨度从几秒到几分钟不等(取决于实际任务)。

【问题讨论】:

  • 我也对这个感兴趣;我们的商店也有类似的问题,但不是在关键位置。

标签: .net console c++-cli


【解决方案1】:

最终我自己找到了答案。两种读取控制台输出的方式都非常实用。问题出在控制台应用程序中。我不知道有必要手动刷新控制台输出以使其可用于其他应用程序。

所以替换后:

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

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

像魅力一样工作。

【讨论】:

    【解决方案2】:

    为什么不将被调用进程的输出重定向到文件并从程序中读取该文件? 如果子进程很好地刷新了它的输出,那么你得到了很好的响应。

    【讨论】:

    • 输出文件也是在进程完成后写入的。
    猜你喜欢
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多