Redirecionamento do teclado para a espera


Как асинхронно захватывать выход процесса в powershell?
Я хочу записать stdout и stderr из процесса, который я запускаю в Powershell script, и выводить его асинхронно на консоль. Я нашел документацию по этому поводу через MSDN и другие блоги.
После создания и запуска приведенного ниже примера я не могу получить какой-либо вывод, который будет отображаться асинхронно. Весь вывод выводится только при завершении процесса.
В этом примере я ожидал увидеть вывод "oi" в командной строке до окончания выполнения программы, потому что должно было быть вызвано событие OutputDataReceived.
Я пробовал это с помощью других исполняемых файлов - java. exe, git. exe и т. д. Все они имеют одинаковый эффект, поэтому мне остается думать, что есть что-то простое, что я не понимаю или пропустили. Что еще нужно сделать для асинхронного чтения stdout?
К сожалению, асинхронное чтение не так просто, если вы хотите сделать это правильно. Если вы вызываете WaitForExit () без тайм-атта, вы можете использовать что-то вроде этой функции, которую я написал (на основе кода С #):
Он фиксирует stdout, stderr и код выхода. Пример использования:
Для получения дополнительной информации и альтернативных реализаций (на С #) прочитайте это сообщение в блоге.
На основе Ответ Александра Обершта Я создал функцию, которая использует тайм-атт и асинхронные классы задач вместо обработчиков событий. Согласно Майк Адельсон.
К сожалению, этот метод (обработчики событий) не дает возможности узнать когда последний бит данных был получен. Потому что все асинхронно, возможно (и я это наблюдал) для событий пожар после возвращения WaitForExit ().
Я не мог заставить любой из этих примеров работать с PS 4.0.
Я хотел запустить boneco aplicar из пакета polvo Implantar (через Deploy. ps1) и посмотреть вывод в режиме реального времени, а не дождаться завершения процесса (через час), поэтому я придумал следующее:
Примеры здесь полезны, но не полностью соответствуют моему варианту использования. Я не хотел вызывать команду и выйти. Я хотел открыть командную строку, отправить ввод, прочитать выход и повторить. Вот мое решение для этого.
Затем из PowerShell добавьте класс и используйте его.
Не забудьте вызвать функцию Dispose () в конце, чтобы очистить процесс, выполняющийся в фоновом режиме. Кроме того, вы можете закрыть этот процесс, выполнив что-то вроде $ cmd. RunCommand ("sair")
Ознакомьтесь с другими вопросами по меткам eventos assíncronos powershell.

System. Diagnostics. Process, RedirectStandardOutput process hanging.
Em um desenvolvimento do nosso aplicativo web interno, estávamos executando de forma síncrona aplicativos de console com certos argumentos e tentando exibir os resultados no front-end.
Quando ativamos o processo, eu consigo ver o processo ser iniciado no gerenciador de tarefas e nunca sai, após um período de tempo (configuração de tempo limite do IIS), o aplicativo da Web expira.
No final, descobrimos que o motivo é devido a uma condição de bloqueio morto entre o processo pai (w3wp) e o processo filho (aplicativo de console).
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 resultar em condições de impasse. 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 grava a transmissão 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 deadlock resulta quando o processo do chamador e filho aguardam um para o outro para concluir uma operação, e nenhum deles pode prosseguir.
A solução é realmente simples, veja o snippet de código abaixo.
// Inicie o processo filho.
Processo p = novo Processo ();
// Redirecione o fluxo de saída do processo filho.
// Não espere que o processo filho saia antes.
// leitura até o final do seu fluxo redirecionado.
// Leia o fluxo de saída primeiro e depois aguarde.
string output = p. StandardOutput. ReadToEnd ();
BTW, a maioria das explicações é do MSDN, mas demorou um pouco para descobrir.
Autor: Saravana Kumar.
Saravana Kumar é o Fundador e CTO do BizTalk360, um software corporativo que atua como uma solução tudo-em-um para melhor administração, operação, suporte e monitoramento de ambientes do Microsoft BizTalk Server. Ver todas as postagens de Saravana Kumar.

C # Hoje.
Deixe o # C # hoje!
Deixe o # C # hoje!
Como evitar deadlocks ao ler o console filho redirecionado no C # 2.
A leitura da saída da criança redirecionada parece ser uma tarefa fácil. Mas há desenvolvedores que lutam com o processo infantil pendurado por causa de bloqueios de leitura / leitura de console. E os deadlocks nunca são fáceis de investigar.
Consideremos um exemplo comum - um processo pai inicia um processo filho e lê toda a saída. Aqui está um exemplo de aplicação que pode simular o cenário.
O aplicativo pode ser executado em dois modos:
Processo principal - executa o processo filho e lê seu processo de saída infantil - imprime um pouco de saída.
Tudo funciona bem, mas consideremos um cenário em que o rendimento da criança é significativo maior.
Desta vez, o processo pai irá pendurar - é um impasse. Por quê? Vamos pensar o que o pai faz - primeiro ele configura o redirecionamento de saída do processo filho.
Em seguida, inicia o processo filho.
O passo consecutivo aguarda a conclusão do processo infantil.
E esse é o ponto onde o processo pai bloqueia com a criança. Por quê? O pai está aguardando que a criança termine e a criança tenha alguma dependência do pai também.
Primeiro, você precisa entender como o redirecionamento de saída funciona. Há um buffer criado para a saída. Quando a criança está escrevendo para o console, ele realmente está escrevendo para o buffer. Se a criança escreve muito, o buffer pode ficar cheio. Nesse caso, a criança trava no Console. Write até o buffer ter algum espaço.
O pai deve ler a saída da criança antes de esperar que a criança termine. Então, para corrigir o impasse, temos que trocar as seguintes linhas.
O código pai completo deve ser mostrado abaixo.
Observe que exatamente o mesmo problema pode acontecer com a saída de erro padrão (stderr). Além disso, um impasse semelhante pode acontecer com a escrita na entrada padrão da criança.
Basicamente você precisa ter muito cuidado e entender o que você está fazendo se quiser ler a entrada / saída da criança de forma síncrona.
Deixe um comentário Cancelar resposta.
2 pensamentos sobre & ldquo; Como evitar deadlocks ao ler o console filho redirecionado em C # & rdquo;
Venceu esse impasse ainda que o processo produza muito em stderr? Eu acho que é realmente seguro, você precisa usar os eventos em vez disso.
Correto, adicionei uma nota sobre o stderr.
Eu concordo que o manuseio assíncrono é uma maneira mais segura. I & # 8217; ll escrever uma postagem sobre isso também.

Redireccionar o teclado de verificação waitforexit
Obter através da App Store Leia esta publicação em nosso aplicativo!
Como obter a mensagem de erro com C #
Para vsinstr - coverage hello. exe, posso usar o código C # da seguinte maneira.
Quando há um erro, recebo a mensagem de erro: Erro VSP1018: VSInstr não suporta binários de processamento que já estão instrumentados. .
Como posso obter esta mensagem de erro com C #?
Eu poderia obter as mensagens de erro das respostas.
Você precisa redirecionar a saída padrão ou o erro padrão. Aqui está um exemplo de código para stdout:
Você deve redirecionar StdError e ler o fluxo para pegar os erros.
Você deve recuperar a saída padrão / erro do chamado processo. Aqui está como fazê-lo:
Supondo que o processo vsinstr. exe escreva esse erro no fluxo de erros padrão, você pode obter a mensagem de erro ao capturar o fluxo de erros padrão do processo. Para fazer isso, você precisará definir a propriedade RedirectStandardError da classe ProcessStartInfo como verdadeira, adicionar um manipulador de eventos ao evento ErrorDataReceived da classe Processo e chamar o método BeginErrorReadLine da classe Processo antes de iniciar o processo vsinstr. exe.
Aqui está algum código de exemplo:
Er - dentro de um bloco try / catch? Estou esquecendo de algo?
. tenha em mente que o ex. Message pode não conter a exepção que você especificou acima, enquanto a exceção interna, e. ex. InnerException pode.
Estou assumindo que você está vendo esta mensagem durante a depuração. Deixe-me saber se isso não era exatamente o que você procurava, mas você poderia usar um bloco de tentativa de captura simples.

Usando Process. BeginOutputReadLine pode levar a linhas de stdout perdidas # 12219.
joelverhagen comentou 30 de setembro de 2018 e # 8226;
Ao escrever código que cria processos filho e precisa capturar stdout, descobri que as linhas de saída perdem a seguinte condição:
muito paralelismo. ProcessStartInfo. RedirectStandardOutput = true Process. OutputDataReceived + = CollectLines (ou seja, usando o fluxo assíncrono) Process. BeginOutputReadLine () Process. WaitForExit (int. MaxValue)
Observe que passar -1 (período de tempo infinito) para WaitForExit não faz com que as linhas desapareçam (com base em meus próprios testes).
Criei um pequeno aplicativo de demonstração para fazer isso. É repro na netlineapp1.0 e net45: processredirect. zip. Basta usar o dotnet run para experimentá-lo.
Dito isto, você pode capturar stdout usando Process. StandardOutput (que é um StreamReader). No entanto, para consumir isso de maneira assíncrona e segura você precisa usar threads / tarefas de fundo. Em outras palavras:
Acho que isso é um problema porque é muito fácil entrar nesta armadilha. Usar os eventos para capturar o resultado é muito conveniente, pois você não precisa se preocupar em criar threads ou tarefas de plano de fundo. Além disso, a internet recomenda esse método:
Eu apenas tentei isso no Windows, Framework 4.5 e Core (netcoreapp1.0). Além disso, toda essa informação está relacionada ao stdout, mas imagino que o stderr tem o mesmo problema. Minha informação de dotnet é:
joelverhagen comentou 30 de setembro de 2018.
Atualizei o aplicativo de teste para suportar sistemas que não sejam do Windows (usando o eco):
Os resultados são os mesmos para Windows, Linux e Mac OS X.
Use as propriedades StreamReader no Processo em vez de eventos, pois você pode perder a saída # 906.
stephentoub comentou 7 de outubro de 2018 e # 8226;
@joelverhagen, para melhor ou pior, o que você está vendo é um design documentado.
Esta sobrecarga garante que todo o processamento foi concluído, incluindo o tratamento de eventos assíncronos para saída padrão redirecionada. Você deve usar essa sobrecarga após uma chamada para a sobrecarga WaitForExit (Int32) quando a saída padrão foi redirecionada para manipuladores de eventos assíncronos.
E para Process. WaitForExit (Int32):
Quando a saída padrão foi redirecionada para manipuladores de eventos assíncronos, é possível que o processamento de saída não seja concluído quando esse método retornar. Para garantir que o tratamento de eventos assíncrono tenha sido concluído, chame a sobrecarga WaitForExit () que não leva nenhum parâmetro depois de receber uma verdade dessa sobrecarga.
Você pode ver aqui que o código explicitamente não aguarda a saída redirecionada para ser concluída se foi passado um tempo limite não-infinito:
Dito isto, não sei por que foi projetado desta forma.
Priya91 comentou 7 de dezembro de 2018.
@joelverhagen Usando WaitForExit sem tempo limite depois que a outra sobrecarga deve desbloqueá-lo, como indicado nos documentos. Ao fechar esta questão, reabra se for necessário assistência adicional.
&cópia de; 2018 GitHub, Inc. Termos Privacidade Segurança Status Ajuda.
Você não pode executar essa ação neste momento.
Você fez login com outra guia ou janela. Recarregue para atualizar sua sessão. Você se separou em outra guia ou janela. Recarregue para atualizar sua sessão.

Comments

Popular Posts