Почему я пропускаю вывод при перенаправлении из процесса? - PullRequest
2 голосов
/ 27 мая 2011

Я вызываю консольное приложение, используя класс Process. Я перенаправляю вывод в файл журнала, но в окне консоли больше сообщений, когда я не перенаправляю вывод, чем в файле журнала, когда я. есть идеи почему?

ProcessStartInfo psi = new ProcessStartInfo();
string filename = @"ProgrammingMaster_LocalPowertrain.exe";
psi.FileName = filename;
string arguments = String.Format("{0} {1} false", InstanceId.ToString(), ManifestFolderPath);
psi.Arguments = arguments;
LogMessage(msgType.Warning, filename + " - " + arguments);
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
psi.RedirectStandardError = true;
psi.RedirectStandardOutput = true;
FBlockProcess = new Process();
FBlockProcess.StartInfo = psi;
FBlockProcess.OutputDataReceived += new DataReceivedEventHandler(FBlockProcess_OutputDataReceived);
FBlockProcess.ErrorDataReceived += new DataReceivedEventHandler(FBlockProcess_ErrorDataReceived);
FBlockProcess.Start();
FBlockProcess.BeginOutputReadLine();
FBlockProcess.BeginErrorReadLine();

в моем обработчике OutputDataReceived я просто добавляю строку в ConcurrentQueue

Edit: Я должен добавить, что я хочу захватить вывод в режиме реального времени или близко к нему. Процесс может занять более 30 минут, мне не нужно долго ждать, чтобы увидеть, что происходит.

Обновление: После вывода первых четырех строк событие OutputDataReceived eventHandler никогда не вызывается, хотя я знаю, что на консоль выводятся еще 10 или 15 строк, когда я не перенаправляю. Любые идеи о том, что может вызвать это?

Ответы [ 2 ]

0 голосов
/ 02 сентября 2016

Я столкнулся с подобной проблемой при попытке взаимодействия с приложением, которое требовало аутентификации. Peek () будет возвращать -1, когда встречаются с причудливыми символами (символы юникода?), А ReadLine () также ненадежен и в конечном итоге блокирует мое приложение, так как кажется, что стандартный поток процесса не был закрыт.

Использование метода Read () было единственным способом убедить меня, что я получил ВСЕ строки и символы. Кроме того, использование обработчиков событий ErrorDataReceived или OutputDataReceived также оказалось НЕОБХОДИМЫМ (пропущенные строки). Ниже показано, как я решил свою проблему и застраховал все строки и символы, которые были получены:

process.Start();
var stdOutput = process.StandardOutput;
StringBuilder fullMessage = new StringBuilder();
while (true)
{
    var character = (char)stdOutput.Read();
    fullMessage.Append(character);

    //Print Out All Characters
    Console.Write(character);
    if (fullMessage.ToString().EndsWith("Enter Password: "))
    {
        //Submit Password To Application
        using(StreamWriter writer = process.StandardInput){
            writer.Write("somepassword");
            writer.Flush();
        }

        break;
    }
}
0 голосов
/ 27 мая 2011

попробуйте этот пример:

public static void Main()
{
    Process p = new Process();
    p.StartInfo.FileName = "cmd.exe";
    p.StartInfo.Arguments = "/c dir *.cs";
    p.StartInfo.UseShellExecute = false;
    p.StartInfo.RedirectStandardOutput = true;
    p.Start();

    string output = p.StandardOutput.ReadToEnd();

    Console.WriteLine("Output:");
    Console.WriteLine(output);    
}

обновление

Я думаю, вы можете попробовать что-нибудь полезное здесь:

http://msdn.microsoft.com/en-us/library/system.diagnostics.process.errordatareceived.aspx

обновление

Я нашел эту ссылку, и "Solution 1" звучит так:

http://www.codeproject.com/Answers/152467/Problem-executing-a-command-line-command-from-Csha.aspx?cmt=49313#answer1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...