2009-10-15 3 views
2

Мне нужно прочитать вывод из встроенного консольного приложения C++ в моей C++ /. NET. Об этом много статей, но большинство ждет, пока процесс не закончится, чтобы прочитать результат, который я не хочу, мне нужно прочитать его сразу же после того, как этот процесс завершился «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 
    } 
} 

исполняемых Выходов много строк текста со временем от нескольких секунд до нескольких минут (в зависимости от фактической задачи).

+0

Меня тоже интересует; у нас есть аналогичная проблема в нашем магазине, хотя и не в критическом месте. –

ответ

1

Мне удалось найти ответ сам в конце. Оба способа чтения консольных выходов прекрасно функционируют. Проблема была в консольном приложении. Я не знал, что необходимо вручную вывести консольный вывод, чтобы сделать его доступным для других приложений.

Таким образом, после замены:

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

с

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

работает как шарм.

0

Почему бы не перенаправить вызванный процесс 'output в файл и прочитать этот файл из вашей программы? Если дочерний процесс хорошо очищает свой выход, тогда вы получили неплохую реакцию.

+0

Выходной файл был записан после завершения процесса. –

Смежные вопросы