System.Diaganostics.Process (когда один процесс внутренне использует другой) - PullRequest
2 голосов
/ 19 января 2010

Я использовал C # System.Diagnostics.Process для мониторинга вывода утилиты командной строки.

Процесс, который я отслеживаю «внутренне», запускает второй процесс, и, как только он это делает, я больше не получаю вывод от объекта процесса.

Что расстраивает, так это то, что если вы выполняете ту же самую команду (которую я запускаю с объектом System.Diagnostics.Process) с cmd.exe (вручную), консоль выводит каждую строку, которую мне нужно видеть в моем Приложение C #!

Однако, если я (для целей тестирования) запускаю cmd.exe с объектом System.Diagnostics.Process и запускаю команду, он по-прежнему прекращает вывод в том же месте, что и ранее (непосредственный запуск process1.exe); в этот момент используется second.exe. Я думал, что этот тест объединит все результаты всех вовлеченных процессов, но это не так. Как я могу получить весь этот вывод в мое приложение C #?

Ответы [ 2 ]

5 голосов
/ 19 января 2010

Причина этого в том, что System.Diagnostics.Process буквально отслеживает только процесс, к которому он подключен.

Один из способов обойти эту проблему - вывести первое приложение, когда оно запускает второе приложение, и когда этот вывод получен, контролировать из основного приложения, что процесс создания из (сейчасв-третьих) приложение.После запуска третьего приложения оно должно появиться в массиве System.Diagnostics.Process.GetProcesses(), и вы можете присоединиться к его событию OutputDataReceived.

Ваш код будет выглядеть примерно так (не проверено):

private void firstProcess_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
    if (e.Data == "Starting next process")
    {
        System.Diagnostics.Process newProcess = null;

        while (newProcess == null)
        {
            System.Diagnostics.Process[] procs = System.Diagnostics.Process.GetProcesses();

            foreach (System.Diagnostics.Process proc in procs)
            {
                if (proc.ProcessName == "newProcess")
                {
                    newProcess = proc;
                    break;
                }
            }

            System.Threading.Thread.Sleep(100);
        }

        newProcess.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(newProcess_OutputDataReceived);
    }
}

void newProcess_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
    // Do something with your data received here.
}

Обратите внимание, что это всего лишь пример, и если ваш третий процесс не запускается или заканчивается слишком быстро, тоэтот метод будет висеть в бесконечном цикле.Этот пример просто предназначен для того, чтобы дать вам знания для создания чего-то, что работает в вашем конкретном случае, с которым я не совсем знаком.Вы должны как минимум убедиться, что цикл while не будет продолжаться вечно, и вам, вероятно, захочется также сделать несколько других настроек.

РЕДАКТИРОВАТЬ: Альтернативно, если вы не можете изменить источникДля первого приложения вы можете просто создать новый поток, который отслеживает таким образом (используя цикл while) и обрабатывать выходные данные третьего процесса в отдельном классе, или просто перенаправить выходные данные третьего процесса вобработчик для вывода второго процесса, чтобы вы могли иметь один метод, обрабатывающий весь вывод для обоих процессов.

1 голос
/ 19 января 2010

Нужно ли вообще запускать cmd.exe?Разве вы не можете просто инициировать процесс для rsync непосредственно в вашем процессе, а затем использовать что-то вроде техник, описанных в этом вопросе , чтобы перехватить результаты выполнения команды, чтобы вы могли работать с ними в своем коде?

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