Thursday 8 March 2018

C # process redirectstandardoutput waitforexit


Processo C # redirectstandardoutput waitforexit
Obter através da App Store Leia esta publicação em nosso aplicativo!
ProcessInfo e RedirectStandardOutput.
Eu tenho um aplicativo que chama outro processo em uma janela de comando e esse processo possui estatísticas de atualização que são enviadas para a janela do console. Eu pensei que esta era uma operação bastante simples, mas não consigo conseguir que funcione. Estou esquecendo de algo?
Idealmente, o que eu gostaria é que o resultado muda dentro desse processo que eu acertei ou os dados entram no leitor que eu obtenho eventos fora dele.
Qualquer ajuda seria excelente, eu sinto que esta é uma questão de novato, mas parece estar faltando alguma coisa.
Já experimentei isso antes. Às vezes, a forma como o processo que você está chamando de saídas para o console não é compatível com esse tipo de redirecionamento de saída. Naquele caso, tive a sorte de poder modificar o processo externo para evitar isso.
Você pode tentar executar seu código em outro processo que saia para o console e veja se ele funciona corretamente. Ele me lê direito agora.
Eu fui e puxei um bloco de código que eu costumava fazer. Isso está em um aplicativo WPF que redireciona a saída do processo para a janela. Observe a ligação do evento. Como isso é WPF, tenho que invocar minha chamada para escrever os dados. Como você não está preocupado com o bloqueio, você pode simplesmente substituir isso por:
Espero que ajude!
Não tenho certeza exatamente sobre o problema em que você está executando, mas se você estiver olhando para atuar no resultado assim que for gerado, tente se conectar ao evento OutputDataReceived do processo. Você pode especificar manipuladores para receber saída de forma assíncrona do processo. Eu usei essa abordagem com sucesso.
Consulte o evento OutputDataReceived Off Process para obter mais informações.
Usando expressões lambda, etc.:
Curiosamente, você não pode ler de saída padrão e erro padrão ao mesmo tempo:
se você redirecionar a saída padrão e o erro padrão e tente ler ambos, por exemplo, usando o seguinte código C #.
string output = p. StandardOutput. ReadToEnd ();
string error = p. StandardError. ReadToEnd ();
Nesse caso, se o processo filho escrever qualquer texto para erro padrão, ele bloqueará o processo, porque o processo pai não pode ler de erro padrão até que ele tenha terminado a leitura da saída padrão. No entanto, o processo pai não será lido a partir da saída padrão até o processo terminar. Uma solução recomendada para esta situação é criar dois tópicos para que seu aplicativo possa ler a saída de cada fluxo em um segmento separado.
O código de fluxo funcionou no VS2018.
Verifique se a saída que você espera não está sendo enviada para a saída StandardError em vez da saída StandardOutput.

Exemplo de uso.
Resolvi assim:
Eu redirecionava a entrada, a saída e o erro e administrai a leitura dos fluxos de saída e erro. Esta solução funciona para o SDK 7- 8.1, tanto para o Windows 7 como para o Windows 8.
Eu tentei fazer uma aula que resolva seu problema usando a leitura de fluxo assíncrono, levando em conta Mark Byers, Rob, Stevejay responde. Ao fazê-lo, percebi que existe um erro relacionado à leitura assíncrona do fluxo de saída do processo.
Você não pode fazer isso:
Você receberá System. InvalidOperationException: StandardOut não foi redirecionado ou o processo ainda não começou.
Então, você deve iniciar a saída assíncrona lida após o processo ser iniciado:
Fazendo isso, faça uma condição de corrida porque o fluxo de saída pode receber dados antes de configurá-lo como assíncrono:
Então algumas pessoas podem dizer que você só precisa ler o fluxo antes de configurá-lo como assíncrono. Mas o mesmo problema ocorre. Haverá uma condição de corrida entre a leitura síncrona e configurará o fluxo em modo assíncrono.
Não há como conseguir uma leitura assíncrona segura de um fluxo de saída de um processo na forma real "Processo" e "ProcessStartInfo" foi projetado.
Você provavelmente está melhor usando a leitura assíncrona, como sugerido por outros usuários para o seu caso. Mas você deve estar ciente de que você pode perder algumas informações devido à condição de corrida.
Nenhuma das respostas acima está fazendo o trabalho.
A solução Rob trava e a solução 'Mark Byers' obtém a exceção descarta. (Eu tentei as "soluções" das outras respostas).
Então eu decidi sugerir outra solução:
Este código é depurado e funciona perfeitamente.
Eu acho que isso é uma abordagem simples e melhor (não precisamos do AutoResetEvent):
Eu estava tendo o mesmo problema, mas a razão era diferente. No entanto, isso aconteceria no Windows 8, mas não no Windows 7. A seguinte linha parece ter causado o problema.
A solução era NÃO desativar UseShellExecute. Agora recebi uma janela popup do Shell, que é indesejável, mas muito melhor do que o programa esperando que nada de particular aconteça. Então eu adicionei o seguinte trabalho para isso:
Agora, o único problema que me incomoda é o porquê isso está acontecendo no Windows 8, em primeiro lugar.
Introdução.
A resposta atualmente aceita não funciona (lança exceção) e há muitas soluções alternativas, mas nenhum código completo. Isso é, obviamente, desperdiçando muito tempo das pessoas porque esta é uma questão popular.
Combinando a resposta de Mark Byers e a resposta de Karol Tyl, escrevi um código completo baseado em como eu quero usar o método Process. Start.
Eu usei-o para criar um diálogo de progresso em torno dos comandos git. É assim que eu usei isso:
Em teoria, você também pode combinar stdout e stderr, mas não testei isso.
Eu sei que isso é velho, mas, depois de ler toda essa página, nenhuma das soluções estava funcionando para mim, embora eu não tentei Muhammad Rehan porque o código era um pouco difícil de seguir, embora eu acho que ele estava no caminho certo . Quando eu digo que não funcionou, isso não é inteiramente verdade, às vezes funcionaria bem, acho que é algo a ver com a duração da saída antes de uma marca EOF.
De qualquer forma, a solução que funcionou para mim era usar diferentes threads para ler o StandardOutput e StandardError e escrever as mensagens.
Espero que isso ajude alguém, que pensou que isso poderia ser tão difícil!
As outras soluções (incluindo o EM0) ainda estão bloqueadas para o meu aplicativo, devido a tempos de espera internos e ao uso de StandardOutput e StandardError pela aplicação gerada. Aqui está o que funcionou para mim:
Editar: inicialização adicionada de StartInfo para codificar a amostra.
Este post talvez esteja desactualizado, mas descobri a principal causa por que normalmente ele trava é devido ao excesso de pilha para o redirectStandardoutput ou se você tem redirectStandarderror.
Como os dados de saída ou os dados de erro são grandes, isso causará um tempo de espera, pois ele ainda está processando por tempo indefinido.

Xamarin.
Propriedade System. Diagnostics. ProcessStartInfo. RedirectStandardOutput.
Obtém ou define um valor que indica se a saída de um aplicativo está gravada no fluxo Process. StandardOutput.
[System. Diagnostics. MonitoringDescription ("saída Standart deste processo é redirecionada.")]
Quando um Processo grava texto em seu fluxo padrão, esse texto normalmente é exibido no console. Ao redirecionar o fluxo Process. StandardOutput, você pode manipular ou suprimir a saída de um processo. Por exemplo, você pode filtrar o texto, formatá-lo de forma diferente ou escrever a saída para o console e um arquivo de log designado.
Você deve definir ProcessStartInfo. UseShellExecute como falso se desejar definir ProcessStartInfo. RedirectStandardOutput como verdadeiro. Caso contrário, a leitura do fluxo Process. StandardOutput lança uma exceção.
O fluxo de Process. StandardOutput redirecionado pode ser lido de forma síncrona ou assíncrona. Métodos como StreamReader. Read, StreamReader. ReadLine e StreamReader. ReadToEnd executam operações de leitura síncrona no fluxo de saída do processo. Essas operações de leitura síncrona não são concluídas até que o Processo associado escreva em seu fluxo Process. StandardOutput ou encerre o fluxo.
Em contraste, Process. BeginOutputReadLine inicia operações de leitura assíncronas no fluxo Process. StandardOutput. Este método habilita um manipulador de eventos designado para a saída do fluxo e retorna imediatamente ao chamador, o que pode executar outro trabalho enquanto a saída do fluxo é direcionada para o manipulador de eventos.
O aplicativo que está processando a saída assíncrona deve chamar o método Process. WaitForExit para garantir que o buffer de saída tenha sido liberado.
As operações de leitura síncrona introduzem uma dependência entre a leitura do chamador a partir do fluxo Process. StandardOutput e a escrita do processo filho a esse fluxo. Essas dependências podem causar condições de bloqueio. Quando o chamador lê do fluxo redirecionado de um processo filho, depende da criança. O chamador aguarda a operação de leitura até que a criança escreva no fluxo ou encerre o fluxo. Quando o processo filho grava dados suficientes para preencher o fluxo redirecionado, ele depende do pai. O processo filho aguarda a próxima operação de gravação até que o pai lê do fluxo completo ou fecha o fluxo. A condição de impasse ocorre quando o processo do chamador e filho aguardam um ao outro para completar uma operação, e nenhuma delas pode continuar. Você pode evitar deadlocks avaliando as dependências entre o chamador eo processo filho.
Por exemplo, o seguinte código C # mostra como ler de um fluxo redirecionado e aguarde até que o processo filho saia.
O exemplo de código evita uma condição de bloqueio chamando p. StandardOutput. ReadToEnd antes de p. WaitForExit. Uma condição de impasse pode resultar se o processo pai chama p. WaitForExit antes de p. StandardOutput. ReadToEnd eo processo filho grava texto suficiente para preencher o fluxo redirecionado. O processo pai aguardaria indefinidamente o processo filho para sair. O processo filho aguardaria indefinidamente para que o pai leia o fluxo completo Process. StandardOutput.
Há um problema semelhante ao ler todo o texto da saída padrão e dos fluxos de erro padrão. Por exemplo, o seguinte código C # executa uma operação de leitura em ambos os fluxos.
O exemplo de código evita a condição de bloqueio executando operações de leitura assíncronas no fluxo Process. StandardOutput. Um estado de impasse resulta se o processo pai chamar p. StandardOutput. ReadToEnd seguido de p. StandardError. ReadToEnd e o processo filho escreve texto suficiente para preencher o fluxo de erros. O processo pai aguardaria indefinidamente o processo filho para fechar o fluxo Process. StandardOutput. O processo filho aguardaria indefinidamente para que o pai leia o fluxo completo Process. StandardError.
Você pode usar operações de leitura assíncronas para evitar essas dependências e seu potencial de impasse. Alternativamente, você pode evitar a condição de bloqueio criando dois tópicos e lendo a saída de cada fluxo em um segmento separado.
Requisitos.
Assembly: System (no System. dll)
Versões de montagem: 1.0.5000.0, 2.0.0.0, 4.0.0.0.
Namespace System. Diagnostics.
Estruturas.
Interfaces.
Enumerações.
Produtos Xamarin para Visual Studio Xamarin Test Cloud Xamarin Insights Xamarin University Xamarin Studio Visual Studio Xamarin. Forms Aplicações pré-construídas Mono Licensing Company Quem somos Clientes Parceiros Blog Empregos Prêmio Pricing Centro de desenvolvedores Começar Guias Recipes Xamarin. iOS APIs Xamarin. Android APIs Xamarin. Mac APIs Fóruns Vídeos Connect Developer Support Resources Consultoria Serviços Contato Vendas Twitter GitHub Stack Overflow Facebook Google+ YouTube.
Xamarin Inc., como uma subsidiária integral da Microsoft que atua como uma entidade jurídica separada, adere à Declaração de Privacidade da Microsoft: Privacidade e biscoitos.

Свойство ProcessStartInfo. RedirectStandardOutput.
Опубликовано: Октябрь 2018.
Получает или задает значение, позволяющее определить, записываются ли текстовые выходные данные приложения в поток Process. StandardOutput.
Значение свойства.
Значение true, если выходные данные должны записываться в Process. StandardOutput; в противном случае - значение false. Значение по умолчанию - falso.
Quando um T: System. Diagnostics. Process grava texto em seu fluxo padrão, esse texto normalmente é exibido no console. Ao configurar P: System. Diagnostics. ProcessStartInfo. RedirectStandardOutput para true para redirecionar o fluxo P: System. Diagnostics. Process. StandardOutput, você pode manipular ou suprimir a saída de um processo. Por exemplo, você pode filtrar o texto, formatá-lo de forma diferente ou escrever a saída para o console e um arquivo de log designado.
Você deve definir P: System. Diagnostics. ProcessStartInfo. UseShellExecute como falso se você quiser definir P: System. Diagnostics. ProcessStartInfo. RedirectStandardOutput para true. Caso contrário, a leitura do fluxo P: System. Diagnostics. Process. StandardOutput lança uma exceção.
O redutor P: System. Diagnostics. Process. StandardOutput stream pode ser lido de forma síncrona ou assíncrona. Métodos como M: System. IO. StreamReader. Read, M: System. IO. StreamReader. ReadLine e M: System. IO. StreamReader. ReadToEnd executam operações de leitura síncrona no fluxo de saída do processo. Essas operações de leitura síncrona não concluem até que o T: System. Diagnostics. Process associado grava seu fluxo P: System. Diagnostics. Process. StandardOutput ou fecha o fluxo.
Em contraste, M: System. Diagnostics. Process. BeginOutputReadLine inicia operações de leitura assíncronas no fluxo P: System. Diagnostics. Process. StandardOutput. Este método permite que um manipulador de eventos designado (veja E: System. Diagnostics. Process. OutputDataReceived) para a saída de fluxo e retorna imediatamente ao chamador, o que pode executar outro trabalho enquanto a saída de fluxo é direcionada para o manipulador de eventos.
O aplicativo que está processando a saída assíncrona deve chamar o método M: System. Diagnostics. Process. WaitForExit para garantir que o buffer de saída tenha sido liberado.
As operações de leitura síncrona introduzem uma dependência entre a leitura do chamador a partir do fluxo P: System. Diagnostics. Process. StandardOutput e a escrita do processo filho a esse fluxo. Essas dependências podem causar condições de bloqueio. Quando o chamador lê do fluxo redirecionado de um processo filho, depende da criança. O chamador aguarda a operação de leitura até que a criança escreva no fluxo ou encerre o fluxo. Quando o processo filho grava dados suficientes para preencher o fluxo redirecionado, ele depende do pai. O processo filho aguarda a próxima operação de gravação até que o pai lê do fluxo completo ou fecha o fluxo. A condição de impasse ocorre quando o processo do chamador e filho aguardam um ao outro para completar uma operação, e nenhuma delas pode continuar. Você pode evitar deadlocks avaliando as dependências entre o chamador eo processo filho.
Por exemplo, o seguinte código C # mostra como ler de um fluxo redirecionado e aguarde até que o processo filho saia.
O exemplo de código evita uma condição de bloqueio chamando p. StandardOutput. ReadToEnd antes de p. WaitForExit. Uma condição de impasse pode resultar se o processo pai chama p. WaitForExit antes de p. StandardOutput. ReadToEnd eo processo filho grava texto suficiente para preencher o fluxo redirecionado. O processo pai aguardaria indefinidamente o processo filho para sair. O processo filho esperaria indefinidamente para o pai ler do fluxo completo P: System. Diagnostics. Process. StandardOutput.
Há um problema semelhante ao ler todo o texto da saída padrão e dos fluxos de erro padrão. Por exemplo, o seguinte código C # executa uma operação de leitura em ambos os fluxos.
O exemplo de código evita a condição de bloqueio executando operações de leitura assíncronas no fluxo P: System. Diagnostics. Process. StandardOutput. Um estado de impasse resulta se o processo pai chamar p. StandardOutput. ReadToEnd seguido de p. StandardError. ReadToEnd e o processo filho escreve texto suficiente para preencher o fluxo de erros. O processo pai aguardaria indefinidamente o processo filho para fechar o fluxo P: System. Diagnostics. Process. StandardOutput. O processo filho esperaria indefinidamente para o pai ler do fluxo completo P: System. Diagnostics. Process. StandardError.
Você pode usar operações de leitura assíncronas para evitar essas dependências e seu potencial de impasse. Alternativamente, você pode evitar a condição de bloqueio criando dois tópicos e lendo a saída de cada fluxo em um segmento separado.

Propriedade ProcessStartInfo. RedirectStandardOutput.
A documentação de referência da API tem uma nova casa. Visite o navegador da API no docs. microsoft para ver a nova experiência.
Obtém ou define um valor que indica se a saída textual de um aplicativo está gravada no fluxo Process. StandardOutput.
Assembly: System (no System. dll)
Valor da propriedade.
Quando um Processo grava texto em seu fluxo padrão, esse texto normalmente é exibido no console. Ao configurar o RedirectStandardOutput para true para redirecionar o fluxo StandardOutput, você pode manipular ou suprimir a saída de um processo. Por exemplo, você pode filtrar o texto, formatá-lo de forma diferente ou escrever a saída para o console e um arquivo de log designado.
Você deve definir UseShellExecute como falso se desejar configurar o RedirectStandardOutput como verdadeiro. Caso contrário, a leitura do fluxo StandardOutput lança uma exceção.
O fluxo de saída StandardOutput redirecionado pode ser lido de forma síncrona ou assíncrona. Métodos como Read, ReadLine e ReadToEnd executam operações de leitura síncrona no fluxo de saída do processo. Essas operações de leitura síncrona não são concluídas até que o Processo associado escreva seu fluxo StandardOutput ou encerre o fluxo.
Em contraste, BeginOutputReadLine inicia operações de leitura assíncronas no fluxo StandardOutput. Este método habilita um manipulador de eventos designado (veja OutputDataReceived) para a saída do fluxo e retorna imediatamente ao chamador, o que pode executar outro trabalho enquanto a saída do fluxo é direcionada para o manipulador de eventos.
O aplicativo que está processando a saída assíncrona deve chamar o método WaitForExit para garantir que o buffer de saída tenha sido liberado.
As operações de leitura síncrona introduzem uma dependência entre a leitura do chamador do fluxo StandardOutput e a escrita do processo filho para esse fluxo. Essas dependências podem causar condições de bloqueio. Quando o chamador lê do fluxo redirecionado de um processo filho, depende da criança. O chamador aguarda a operação de leitura até que a criança escreva no fluxo ou encerre o fluxo. Quando o processo filho grava dados suficientes para preencher o fluxo redirecionado, ele depende do pai. O processo filho aguarda a próxima operação de gravação até que o pai lê do fluxo completo ou fecha o fluxo. A condição de impasse ocorre quando o processo do chamador e filho aguardam um ao outro para completar uma operação, e nenhuma delas pode continuar. Você pode evitar deadlocks avaliando as dependências entre o chamador eo processo filho.
Por exemplo, o seguinte código C # mostra como ler de um fluxo redirecionado e aguarde até que o processo filho saia.
O exemplo de código evita uma condição de bloqueio chamando p. StandardOutput. ReadToEnd antes de p. WaitForExit. Uma condição de impasse pode resultar se o processo pai chama p. WaitForExit antes de p. StandardOutput. ReadToEnd eo processo filho grava texto suficiente para preencher o fluxo redirecionado. O processo pai aguardaria indefinidamente o processo filho para sair. O processo filho esperaria indefinidamente para o pai ler do fluxo de StandardOutput completo.
Há um problema semelhante ao ler todo o texto da saída padrão e dos fluxos de erro padrão. Por exemplo, o seguinte código C # executa uma operação de leitura em ambos os fluxos.
O exemplo de código evita a condição de bloqueio executando operações de leitura assíncronas no fluxo StandardOutput. Um estado de impasse resulta se o processo pai chamar p. StandardOutput. ReadToEnd seguido de p. StandardError. ReadToEnd e o processo filho escreve texto suficiente para preencher o fluxo de erros. O processo pai aguardaria indefinidamente o processo filho para fechar o fluxo StandardOutput. O processo filho esperaria indefinidamente para o pai ler do fluxo completo do StandardError.
Você pode usar operações de leitura assíncronas para evitar essas dependências e seu potencial de impasse. Alternativamente, você pode evitar a condição de bloqueio criando dois tópicos e lendo a saída de cada fluxo em um segmento separado.

No comments:

Post a Comment