Pergunta

Eu tenho usado C# System.Diagnostics.Process Para monitorar a saída de um utilitário de linha de comando.

O processo que estou monitorando "internamente" inicia um segundo processo e, assim que o fizer, não recebo mais saída do objeto do processo.

O que é frustrante é, se você executar o mesmo comando (que estou lançando com o objeto System.Diagnostics.Process) com cmd.exe (manualmente), o console produz todas as linhas que eu preciso estar vendo no meu aplicativo C#!

No entanto, se eu (para fins de teste) iniciar o CMD.exe com o objeto System.diagnostics.process e executar o comando, ele ainda para de produzir no mesmo ponto que fez anteriormente (iniciando o Process1.exe diretamente); No momento, o segundo.exe é utilizado. Eu pensei que esse teste consolidaria toda a saída de todos os processos envolvidos, mas não o fez. Como posso obter toda essa saída no meu aplicativo C#?

Foi útil?

Solução

A razão para isso é que o System.Diagnostics.Process está literalmente monitorando apenas o processo ao qual está ligado.

Uma maneira de contornar esse problema seria o seu primeiro aplicativo para a saída quando estiver iniciando o segundo aplicativo e, quando essa saída é recebida, monitore a sua aplicação principal para a criação do processo a partir do aplicativo (agora terceiro). Uma vez que o terceiro aplicativo seja iniciado, deve aparecer no System.Diagnostics.Process.GetProcesses() Array, e você pode então se conectar ao seu OutputDataReceived evento.

Seu código seria então algo assim (não testado):

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

Observe que este é apenas uma amostra e, se o seu terceiro processo não iniciar ou terminar muito rapidamente, esse método ficará em um loop infinito. Esta amostra é simplesmente destinada a fornecer o conhecimento para criar algo que funcione no seu caso específico, com o qual não estou totalmente familiarizado. Você deve, no mínimo, garantir que o loop enquanto continue para sempre, e provavelmente também desejará fazer alguns outros ajustes.

Editar: alternadamente, se você não puder modificar a fonte para o primeiro aplicativo, poderá simplesmente criar um novo segmento que monitorou dessa maneira (usando o loop while) constantemente e lidou com a saída do terceiro processo em uma classe separada, ou Basta redirecionar a saída do terceiro processo para o manipulador para a saída do segundo processo, para que você possa ter um único método lidando com toda a saída para ambos os processos.

Outras dicas

Você precisa lançar o CMD.exe? Você não pode simplesmente iniciar o processo para o RSYNC diretamente em seu processo e depois usa algo como as técnicas descritas em essa questão Para capturar a saída da execução do comando para que você possa trabalhar com eles em seu código?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top