代码之家  ›  专栏  ›  技术社区  ›  Matěj Zábský

从控制台程序读取输出

  •  2
  • Matěj Zábský  · 技术社区  · 16 年前

    我需要在C++/NET中读取来自原生C++控制台应用程序的输出。关于这一点,有很多文章,但大多数都要等到进程结束后才能读取输出,我不想这样做,我需要在进程“完成”之后立即读取输出(这样做时不想阻塞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);
    

    以及thread函数,它等待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
        }   
    }
    

    流程可执行文件在一段时间内输出多行文本,范围从几秒到几分钟(取决于实际任务)。

    2 回复  |  直到 16 年前
        1
  •  1
  •   Matěj Zábský    16 年前

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

    因此更换后:

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

    具有

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

    很有魅力。

        2
  •  0
  •   Dénes Tarján    16 年前

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

    推荐文章