Wednesday 16 May 2018

Redirectstandarderror waitforexit


Redirectstandarderror waitforexit
Resumo Especifica um conjunto de valores usados ​​ao iniciar um processo. Sintaxe C #:
Você pode usar a classe ProcessStartInfo para obter maior controle sobre o processo iniciado. Você deve definir pelo menos a propriedade ProcessStartInfo. FileName, manualmente ou usando o construtor. O nome do arquivo é qualquer aplicativo ou documento. Aqui, um documento é definido como qualquer tipo de arquivo que tenha uma ação aberta ou padrão associada a ele. Você pode ver os tipos de arquivos registrados e seus aplicativos associados ao seu computador usando a caixa de diálogo Opções de Pasta disponível no sistema operacional. O botão Avançado leva a uma caixa de diálogo que mostra se há uma ação aberta associada a um tipo de arquivo registrado específico.
Além disso, você pode definir outras propriedades que definem ações a serem executadas com esse arquivo. Você pode especificar um valor específico para o tipo da propriedade ProcessStartInfo. FileName para a propriedade System. Diagnostics. ProcessStartInfo. Verb (não suportada na CLI de origem compartilhada). Por exemplo, você pode especificar "imprimir" para um tipo de documento. Além disso, você pode especificar valores de propriedade ProcessStartInfo. Arguments para serem argumentos de linha de comando para passar para o procedimento aberto do arquivo. Por exemplo, se você especificar um aplicativo de editor de texto na propriedade ProcessStartInfo. FileName, poderá usar a propriedade ProcessStartInfo. Arguments para especificar um arquivo de texto a ser aberto pelo editor.
A entrada padrão geralmente é o teclado, e a saída padrão e o erro geralmente são a tela do monitor. No entanto, você pode usar as propriedades ProcessStartInfo. RedirectStandardInput, ProcessStartInfo. RedirectStandardOutput e ProcessStartInfo. RedirectStandardError para fazer com que o processo obtenha entrada ou retorne a saída para um arquivo ou outro dispositivo. Se você utilizar as propriedades Process. StandardInput, Process. StandardOutput ou Process. StandardError no componente Process, deverá primeiro configurar o valor correspondente na propriedade ProcessStartInfo. Caso contrário, o sistema lançará uma exceção quando você ler ou gravar no fluxo.
Configure ProcessStartInfo. UseShellExecute para especificar se deve iniciar o processo usando o shell do sistema operacional.
Você pode alterar o valor de qualquer propriedade ProcessStartInfo até a hora em que o processo é iniciado. Depois de iniciar o processo, alterar esses valores não tem efeito.
Lista de Membros System. Diagnostics. ProcessStartInfo:
Inicializa uma nova instância da classe ProcessStartInfo sem especificar um nome de arquivo com o qual iniciar o processo.

o log de Walter.
. Escrevendo enquanto aprende.
Sexta-feira, 18 de novembro de 2011.
Process. WaitForExit (Int32) trava o problema.
Como você pode ver, o código inicia um processo "cmd. exe" e passa para ele o comando que eu quero executar.
No código eu usei o comando ping - t 8.8.8.8 que, por causa da opção - t, pinga o host sem parar. O que acontece? O processo "cmd. exe" juntamente com o comando ping - t nunca sai e nunca fecha o fluxo stdout e, portanto, o código trava no Output = process. StandardOutput. ReadToEnd (); linha porque não pode ter sucesso lendo todo o fluxo.
O mesmo acontece também se um comando em um arquivo de lote for interrompido por algum motivo e, portanto, o código acima poderia funcionar continuamente por anos e, em seguida, travar repentinamente sem nenhum motivo aparente.
Você pode experimentar um deadlock se o comando que você anexar a "cmd. exe" ou o processo que você está chamando preencher a saída padrão ou o erro padrão. Isso porque nosso código não pode alcançar as linhas.
Na verdade, o processo filho (o comando ping ou um arquivo em lote ou qualquer outro processo que você esteja executando) não pode continuar se nosso programa não ler os buffers preenchidos dos fluxos e isso não pode acontecer porque o código está pendurado na linha com o processo. WaitForExit (), que irá esperar eternamente para o projeto filho sair.
O tamanho padrão de ambos os fluxos é de 4096 bytes. Você pode testar esses dois tamanhos com esses arquivos em lotes:

Propriedade Process. StandardError.
A documentação de referência da API tem uma nova casa. Visite o Navegador da API em docs. microsoft para ver a nova experiência.
Obtém um fluxo usado para ler a saída de erro do aplicativo.
Assembly: System (no System. dll)
Valor da propriedade.
Um StreamReader que pode ser usado para ler o fluxo de erros padrão do aplicativo.
O fluxo StandardError foi aberto para operações de leitura assíncrona com BeginErrorReadLine.
Quando um processo grava texto em seu fluxo de erro padrão, esse texto é normalmente exibido no console. Ao redirecionar o fluxo StandardError, você pode manipular ou suprimir a saída de erro de um processo. Por exemplo, você pode filtrar o texto, formatá-lo de maneira diferente ou gravar a saída no console e em um arquivo de log designado.
Para usar o StandardError, você deve definir ProcessStartInfo. UseShellExecute como false e deve definir ProcessStartInfo. RedirectStandardError como true. Caso contrário, a leitura do fluxo StandardError gerará uma exceção.
O fluxo StandardError 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 de erro do processo. Essas operações de leitura síncrona não são concluídas até que o Processo associado grave em seu fluxo StandardError ou feche o fluxo.
Por outro lado, BeginErrorReadLine inicia operações de leitura assíncrona no fluxo StandardError. Esse método ativa um manipulador de eventos designado para a saída do fluxo e retorna imediatamente ao responsável pela chamada, que pode executar outro trabalho enquanto a saída do fluxo é direcionada para o manipulador de eventos.
As operações de leitura síncrona introduzem uma dependência entre a leitura do responsável pela chamada do fluxo StandardError e a gravação do processo filho nesse fluxo. Essas dependências podem resultar em condições de deadlock. Quando o chamador lê o fluxo redirecionado de um processo filho, ele depende do filho. O chamador aguarda na operação de leitura até que o filho grave no fluxo ou feche o fluxo. Quando o processo filho grava dados suficientes para preencher seu fluxo redirecionado, ele depende do pai. O processo filho aguarda na próxima operação de gravação até que o pai leia o fluxo completo ou feche o fluxo. A condição de deadlock resulta quando o chamador e o processo filho aguardam um ao outro para concluir uma operação e nenhum deles pode prosseguir. Você pode evitar deadlocks avaliando dependências entre o chamador e o processo filho.
O seguinte código C #, por exemplo, mostra como ler de um fluxo redirecionado e aguardar a saída do processo filho.
O exemplo de código evita uma condição de deadlock chamando p. StandardError. ReadToEnd antes de p. WaitForExit. Uma condição de deadlock pode resultar se o processo pai chama p. WaitForExit antes de p. StandardError. ReadToEnd e o processo filho grava texto suficiente para preencher o fluxo redirecionado. O processo pai aguardaria indefinidamente que o processo filho fosse encerrado. O processo filho esperaria indefinidamente que o pai lesse o fluxo completo do StandardError.
Há um problema semelhante quando você lê todo o texto da saída padrão e dos fluxos de erro padrão. O seguinte código C #, por exemplo, executa uma operação de leitura nos dois fluxos.
O exemplo de código evita a condição de deadlock executando operações de leitura assíncrona no fluxo StandardOutput. Uma condição de deadlock resulta se o processo pai chamar p. StandardOutput. ReadToEnd seguido por p. StandardError. ReadToEnd e o processo filho grava texto suficiente para preencher seu fluxo de erro. O processo pai esperaria indefinidamente que o processo filho fechasse seu fluxo StandardOutput. O processo filho esperaria indefinidamente que o pai lesse o fluxo completo do StandardError.
Você pode usar operações de leitura assíncronas para evitar essas dependências e seu potencial de deadlock. Como alternativa, você pode evitar a condição de deadlock criando dois threads e lendo a saída de cada fluxo em um thread separado.
Você não pode mesclar operações de leitura assíncrona e síncrona em um fluxo redirecionado. Depois que o fluxo redirecionado de um processo é aberto no modo assíncrono ou síncrono, todas as operações de leitura adicionais nesse fluxo devem estar no mesmo modo. Por exemplo, não siga BeginErrorReadLine com uma chamada para ReadLine no fluxo StandardError ou vice-versa. No entanto, você pode ler dois fluxos diferentes em modos diferentes. Por exemplo, você pode chamar BeginOutputReadLine e, em seguida, chamar ReadLine para o fluxo StandardError.

Propriedade ProcessStartInfo. RedirectStandardError.
A documentação de referência da API tem uma nova casa. Visite o Navegador da API em docs. microsoft para ver a nova experiência.
Obtém ou define um valor que indica se a saída de erro de um aplicativo é gravada no fluxo Process. StandardError.
Assembly: System (no System. dll)
Valor da propriedade.
Quando um processo grava texto em seu fluxo de erro padrão, esse texto é normalmente exibido no console. Ao redirecionar o fluxo StandardError, você pode manipular ou suprimir a saída de erro de um processo. Por exemplo, você pode filtrar o texto, formatá-lo de maneira diferente ou gravar a saída no console e em um arquivo de log designado.
Você deve definir UseShellExecute como false se quiser definir RedirectStandardError como true. Caso contrário, a leitura do fluxo StandardError gerará uma exceção.
O fluxo StandardError 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 de erro do processo. Essas operações de leitura síncrona não são concluídas até que o Processo associado grave em seu fluxo StandardError ou feche o fluxo.
Por outro lado, BeginErrorReadLine inicia operações de leitura assíncrona no fluxo StandardError. Esse método ativa um manipulador de eventos designado para a saída do fluxo e retorna imediatamente ao responsável pela chamada, 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 responsável pela chamada do fluxo StandardError e a gravação do processo filho nesse fluxo. Essas dependências podem causar condições de deadlock. Quando o chamador lê o fluxo redirecionado de um processo filho, ele depende do filho. O chamador aguarda a operação de leitura até que o filho grave no fluxo ou feche o fluxo. Quando o processo filho grava dados suficientes para preencher seu fluxo redirecionado, ele depende do pai. O processo filho aguarda a próxima operação de gravação até que o pai leia o fluxo completo ou feche o fluxo. A condição de deadlock resulta quando o chamador e o processo filho esperam um pelo outro para concluir uma operação e nenhum deles pode continuar. Você pode evitar deadlocks avaliando dependências entre o chamador e o processo filho.
Por exemplo, o seguinte código C # mostra como ler de um fluxo redirecionado e aguardar o processo filho para sair.
O exemplo de código evita uma condição de deadlock chamando p. StandardError. ReadToEnd antes de p. WaitForExit. Uma condição de deadlock pode resultar se o processo pai chama p. WaitForExit antes de p. StandardError. ReadToEnd e o processo filho grava texto suficiente para preencher o fluxo redirecionado. O processo pai aguardaria indefinidamente que o processo filho fosse encerrado. O processo filho esperaria indefinidamente que o pai lesse o fluxo completo do StandardError.
Há um problema semelhante quando você lê 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 nos dois fluxos.
O exemplo de código evita a condição de deadlock executando operações de leitura assíncrona no fluxo StandardOutput. Uma condição de deadlock resulta se o processo pai chamar p. StandardOutput. ReadToEnd seguido por p. StandardError. ReadToEnd e o processo filho grava texto suficiente para preencher seu fluxo de erro. O processo pai esperaria indefinidamente que o processo filho fechasse seu fluxo StandardOutput. O processo filho esperaria indefinidamente que o pai lesse o fluxo completo do StandardError.
Você pode usar operações de leitura assíncronas para evitar essas dependências e seu potencial de deadlock. Como alternativa, você pode evitar a condição de deadlock criando dois threads e lendo a saída de cada fluxo em um thread separado.
O exemplo a seguir usa o comando net use junto com um argumento fornecido pelo usuário para mapear um recurso de rede. Em seguida, ele lê o fluxo de erro padrão do comando net e o grava no console.

Redirectstandarderror waitforexit
Eu estou tentando iniciar um processo e pegue o StandardOutput e StandardError usando EventHandlers e BeginOutputReadLine. Eu posso iniciar o processo, mas recebo.
Exceção chamando & quot; BeginOutputReadLine & quot; com & quot; 0 & quot; argumento (s): & quot; Não é possível misturar operação síncrona e assíncrona no fluxo do processo. & quot;
Aqui está a minha função de lançamento:
Estou violando o modelo de segmentação Powershell? Obrigado!
Eu estou tentando iniciar um processo e pegue o StandardOutput e StandardError usando EventHandlers e BeginOutputReadLine. Eu posso iniciar o processo, mas recebo.
Exceção chamando & quot; BeginOutputReadLine & quot; com & quot; 0 & quot; argumento (s): & quot; Não é possível misturar operação síncrona e assíncrona no fluxo do processo. & quot;
A mensagem de erro está dizendo o que você está fazendo errado.
Você não pode atribuir funções a um processo síncrono. As funções não são delegadas, portanto, não funcionarão. Você precisa usar um modelo de evento ou usar a variação de asynch.
Use isso como um modelo:
Marcado como Resposta Oliver Lipkau Moderator quarta-feira, 12 de outubro de 2011 2:32.
Todas as respostas.
Eu acredito que você tenha alguns erros no seu código. Eu sou a pessoa mais humilde que você já conheceu.
Eu estou tentando iniciar um processo e pegue o StandardOutput e StandardError usando EventHandlers e BeginOutputReadLine. Eu posso iniciar o processo, mas recebo.
Exceção chamando & quot; BeginOutputReadLine & quot; com & quot; 0 & quot; argumento (s): & quot; Não é possível misturar operação síncrona e assíncrona no fluxo do processo. & quot;
A mensagem de erro está dizendo o que você está fazendo errado.
Você não pode atribuir funções a um processo síncrono. As funções não são delegadas, portanto, não funcionarão. Você precisa usar um modelo de evento ou usar a variação de asynch.
Use isso como um modelo:
Marcado como Resposta Oliver Lipkau Moderator quarta-feira, 12 de outubro de 2011 2:32.
Ok, eu não entendi a implementação do BeginOutputReadline. Eu pensei que isso funcionaria com o. WaitForExit - olhando para ele agora, vejo por que isso não acontece.
Em VB, eu sei como 1) gerar threads para lidar com isso e eu sei que você pode colocar o processo em um loop 2) até que seja concluído como uma maneira de lidar com isso.
Eu não quero fazer # 2. Existe uma maneira multithreaded ou assíncrona para ler a saída de um determinado processo como o processo está gerando?
Ok, eu não entendi a implementação do BeginOutputReadline. Eu pensei que isso funcionaria com o. WaitForExit - olhando para ele agora, vejo por que isso não acontece.
Em VB, eu sei como 1) gerar threads para lidar com isso e eu sei que você pode colocar o processo em um loop 2) até que seja concluído como uma maneira de lidar com isso.
Eu não quero fazer # 2. Existe uma maneira multithreaded ou assíncrona para ler a saída de um determinado processo como o processo está gerando?
Na verdade, a menos que você queira criar um delegado de evento. Mas então este é o PowerShell, não é VB.
Você pode começar aqui e ver se o evento que você está procurando pode ser "viciado"
help Register-ObjectEvent - full.
A resposta marcada não resolve o problema com o qual o OP está lutando - isto é, redirecionando StdErr e StdOut e sofre com o bug de conflito discutido aqui:
& quot; Uma condição de deadlock pode resultar se o processo pai chama p. WaitForExit antes de p. StandardOutput. ReadToEnd e o processo filho grava texto suficiente para preencher o fluxo redirecionado. O processo pai aguardaria indefinidamente que o processo filho fosse encerrado. O processo filho esperaria indefinidamente que o pai lesse o fluxo StandardOutput completo. & Quot;
Eu também estou tentando a melhor resposta para fazer este trabalho no Powershell, mas todos os exemplos de código que estou executando em que usam System. Diagnostics. Process no powersehll estão replicando o deadlock nesta implementação ou não estão redirecionando stderr e stdout.
A solução que estou usando usa o cmdlet Start-Process da seguinte maneira:
Não é uma ótima solução, pois só redirecionará stdout e stderr para um arquivo de texto. mas funcionará o tempo todo e redirecionará stdout e stderr.
Se formos usar saída redirecionada, não usaremos espera. Esse foi o design de CreateProcess desde o NT4.
O uso de arquivos para capturar a saída funcionará porque um fluxo é anexado e envia uma leitura constante para o fluxo de saída. O fluxo de saída nunca é suspenso. Yu não pode fazer isso em um loop de código. O córrego corre o contexto do sistema do pecado eu acredito e começarei sempre a possibilidade de ler. A espera está no seu thread, então você não pode fazer uma leitura manual. É um impasse como afirmado.
O uso da leitura do console é geralmente porque estamos procurando por um prompt. Nesse caso, nunca esperamos a conclusão. O código ZTHe provavelmente será enviado para 'quit' e nós iremos verificar o processo e girá-lo até que ele seja desligado.
A questão aqui é que não podemos gerar um thead. Em VB ou C #, C nós apenas usamos threads separe para IO e um para espera. Melhor ainda, eu usaria um semáforo como ele pode capturar dinamicamente um desligamento inesperado.
Talvez a próxima versão do PowerSHell tenha boas possibilidades de multithreading.
Esta é apenas mais uma lição de que o Powershell é uma linguagem de script, não uma linguagem de programação e, por mais poderosa que seja, existem armadilhas.
O código de exemplo da Microsoft simplesmente não é abrangente o suficiente para um hacker Powerhell perceber que eles não podem chegar lá a partir daqui. Isso é o que me pegou e acredito no OP também, porque houve uma certa expectativa de que BeginOutputReadline implementou a mágica para fazer com que funcionasse threads que teriam resolvido o problema de bloqueio. Não, então acabamos aqui.
E uma ligeira correcção ao meu código - deixei o sinalizador - wait que é necessário para o resto do código funcionar:
Esta é apenas mais uma lição de que o Powershell é uma linguagem de script, não uma linguagem de programação e, por mais poderosa que seja, existem armadilhas.
O código de exemplo da Microsoft simplesmente não é abrangente o suficiente para um hacker Powerhell perceber que eles não podem chegar lá a partir daqui. Isso é o que me pegou e acredito no OP também, porque houve uma certa expectativa de que BeginOutputReadline implementou a mágica para fazer com que funcionasse threads que teriam resolvido o problema de bloqueio. Não, então acabamos aqui.
E uma ligeira correcção ao meu código - deixei o sinalizador - wait que é necessário para o resto do código funcionar:
Certo. O PowerShell é propositadamente limitado para torná-lo mais seguro para a população em geral e para reduzir os problemas que ocorrem com as linguagens compiladas.
Sim - o sinalizador de espera ajudaria, pois o arquivo pode não ter terminado o spool antes de o programa ser encerrado.
O Start-Process é um wrapper fraco na API do processo, mas protege os desavisados ​​dos deadlocks porque você não pode redirecionar a entrada, exceto de um arquivo.
Você não precisa de esperar para redirecionar. Você precisa esperar pelos arquivos e como uma maneira fácil de detectar a terminação. Usando a API, isso tem que ser feito consultando o objeto de processo ou extraindo a saída e aguardando que o processo envie sua mensagem de término e então gire o status.
Isso é tudo demais para os administradores de scripts e, como você apontou, os deixará sem problemas.

Meu pequeno mundo e tudo ao seu redor.
Apenas mais um blog sobre tecnologia.
Tagged com ProcessStartInfo
Descarregando o arquivo no MySQL usando C #
Dumping arquivo no MySQL sempre fácil com o prompt de comando, basta digitar.
c: \ & gt; seu caminho do servidor mysql \ bin \ mysql. exe - uroot - prootpass - hsomehost yourdb & lt; yoursourcefile. sql.
em C # nós não conseguimos fazer exatamente isso.
Então como? Obrigado google, encontrei site que me mostra como, mas é muito complexo, então ajuste-o apenas para minha necessidade.
Arquivo StreamWriter = new StreamWriter (OpenFileDialog. FileName. Replace (& # 8220; \\ & # 8220;, & # 8221; \\\\ & # 8220;)));
ProcessStartInfo proc = new ProcessStartInfo ();
proc. FileName = & # 8220; c: \ & gt; o caminho do seu servidor mysql \ bin \ mysql. exe & # 8220 ;;
Processo p = Process. Start (proc);
Primeiro definimos o arquivo como StreamWriter, a função de abrir o arquivo de origem;
Em seguida, definimos proc como ProcessStartInfo, a função de criar um processo mysql. exe e nos fornecer a capacidade de redirecionar a E / S ao invés da E / S comum.
O processo de E / S é definido em RedirectStandardInput, RedirectStandardOutput e RedirectStandardError. Se quisermos capturar a E / S, simplesmente declaramos como verdadeira, se não apenas declarada como falsa.
Normalmente, o processo do console sempre aparece nas janelas de prompt de comando, portanto, apenas definimos CreateNoWindow = true.
Depois disso, iniciamos o processo por Process. start (proc), a entrada será redirecionada para sw usando sw. WriteLine (), que estará aceitando a entrada de file. ReadToEnd (); e finalmente sw. WriteLine (& # 8220; exit & # 8221;); lembre-se de escrever exit, então o mysql irá fechar.
existe outro site, eu atualizo isso assim que me lembro.
Dumping MySQL em arquivo com c #
Nós todos sabemos dumping banco de dados MySQL do prompt de comando deve ser assim.
c: \ & gt; seu caminho do servidor mysql \ bin \ mysqldump. exe - uroot - prootpass - hsomehost yourdb & gt; yourtargetfile. sql.
mas como fazer isso em c #?
Por que com o problema, porque o C # não nos permite usar o & # 8220; & gt; & # 8221; assinar, e estamos escrevendo em c #, correto? Então nós temos que fazer isso no caminho C #.
depois de caçar com a ajuda do google, descobri que é possível usar ProcessStartInfo e StreamWriter.
Arquivo StreamWriter = new StreamWriter (OpenFileDialog. FileName. Replace (& # 8220; \\ & # 8220;, & # 8221; \\\\ & # 8220;)));
ProcessStartInfo proc = new ProcessStartInfo ();
proc. FileName = & # 8220; c: \ caminho do seu servidor mysql \ bin \ mysqldump. exe & # 8220 ;;
Processo p = Process. Start (proc);
O que código acima faz?
Primeiro definimos o arquivo como StreamWriter, para criar um arquivo de texto;
Em seguida, definimos proc como ProcessStartInfo, a função de criar um processo mysqldump. exe e fornecer-nos a capacidade de redirecionar a E / S em vez da E / S usual.
O processo de E / S é definido em RedirectStandardInput, RedirectStandardOutput e RedirectStandardError. se quisermos capturar a E / S, simplesmente declaramos como verdadeira, se não apenas declarada como falsa.
Normalmente, o processo do console sempre aparece nas janelas de prompt de comando, portanto, apenas definimos CreateNoWindow = true.

No comments:

Post a Comment