Friday, 3 November 2017

Redirectstandardoutput Waitforexit C #


Eu tenho um aplicativo que chama outro processo em uma janela de comando e esse processo tem estatísticas de atualização que saem para a janela do console. Eu pensei que esta era uma operação bastante simples, mas eu não consigo fazer isso funcionar. Estou perdendo algo Idealmente o que eu gostaria é como as mudanças de saída dentro desse processo eu bati ou dados entra no leitor que eu recebo eventos fora dele. Qualquer ajuda seria ótimo, eu sinto que esta é uma pergunta novato, mas parecem estar faltando alguma coisa. Perguntei Jul 17 09 at 22:33 Ive experimentado isso antes. Às vezes, a maneira pela qual o processo youre chamando saídas para o console não é compatível com esse tipo de redirecionamento de saída. Ive sido a sorte o suficiente neste caso para ser capaz de modificar o processo externo para contornar isso. Você pode tentar executar seu código em outro processo que saídas para o console e ver se ele funciona corretamente. Lê sobre direito a mim agora. Eu fui e puxei um bloco de código Ive usado para fazer isso. Isso é em um aplicativo WPF que redireciona a saída do processo para a janela. Observe a vinculação do evento. Uma vez que este é WPF eu tenho que invocar a minha chamada para escrever os dados para fora. Uma vez que você não está preocupado com o bloqueio, ou deve ser capaz de simplesmente substituir isso por: Espero que isso ajude Interessantemente você não pode ler a partir da saída padrão e erro padrão ao mesmo tempo: se você redirecionar tanto padrão de saída e erro padrão e, em seguida, , Por exemplo usando o seguinte código C. String p. StandardOutput. ReadToEnd () string error p. StandardError. ReadToEnd () Neste caso, se o processo filho escreve qualquer texto para o erro padrão ele irá bloquear o processo, porque o processo pai não pode ler a partir do erro padrão até que ele tenha Terminou a leitura da saída padrão. No entanto, o processo pai não lerá de saída padrão até que o processo termina. Uma solução recomendada para esta situação é criar dois threads para que o aplicativo pode ler a saída de cada fluxo em um segmento separado. Estou escrevendo um wrapper VB. NET em torno de algum código Fortran antigo (3 módulos exe). Usando o Process. StartInfo. RedirectStandardOutput funciona para dois dos módulos, mas o terceiro módulo trava quando eu definir o RedirectStandardOutput verdadeira. Posso executar cada um dos programas Fortran a partir da linha de comando mesmo redirecionando sua saída padrão para um arquivo com o comando redirecionamento gt do DOS. Todas as idéias o que está causando isso / que outras opções podem ser necessárias para executá-lo desta forma Obrigado Dave Taylor segunda-feira, 01 de fevereiro de 2010 2:42 Respostas Você está caindo em uma armadilha que é documentada - chamar WaitForExit antes de ReadToEnd. Sugiro que você leia a seção de observações da propriedade Process. StandardOuput: quot condição de deadlock pode resultar se o pai processo chama p. WaitForExit antes p. StandardOutput. ReadToEnd eo processo filho grava texto suficiente para preencher o fluxo redirecionado. O processo pai esperaria indefinidamente para o processo filho para sair. O processo filho iria esperar indefinidamente para o pai para ler o fluxo completo StandardOutput. quot Aqui está a documentação. Também contém informações sobre como evitar esta situação. HTH Tom Shelton Proposta como resposta por Cor Ligthert MVP terça-feira, 02 de fevereiro de 2010 18:06 Marcado como resposta por MartinXie Moderador segunda-feira, 8 de fevereiro de 2010 3:12 terça-feira, 02 de fevereiro de 2010 17:30 Todas as respostas Mais provável , Você escreveu algo errado em seu código naquele terceiro módulo. Monday, February 01, 2010 5:14 AM Enquanto não há dúvida de que quotsomething é wrongquot Eu não acredito que ele esteja no módulo. exe, ou seja, ele funciona bem quando a saída padrão não é redirecionada, mas trava quando eu definir o processo. Startinfo. RedirectStandardOutput TRUE. E uma vez que ele funciona com redirecionamento DOS (ou seja, C: gtmodule3.exe gt output. txt gera o arquivo output. txt esperado), eu suponho que o problema com o redirecionamento é específico para a maneira. NET está criando o processo versus executá-lo a partir do comando linha. Terça-feira, 02 de fevereiro de 2010 3:13 AM Eu suponho que o problema com o redirecionamento é específico para a forma como o. NET está criando o processo versus executá-lo a partir da linha de comando. Isso está sob seu controle. Qual é o código para os wrappers que você está escrevendo, e como o código que você usou para o wrapper para o terceiro módulo diferem do código que você usou para os wrappers para os outros dois módulos Terça-feira, 02 de fevereiro de 2010 3:17 AM Nós simplesmente não podemos ajudá-lo se não vemos um pedaço de código que dá errado. O redirecionamento do Process Start é sair direto, mas sem código é melhor ir para um cassino. O código abaixo é usado para executar dois dos três módulos, a segunda seção GENERATE WALL DATA é o que Falha. Se eu definir proc. StartInfo. RedirectStandardOutput falso na linha marcada com ele prossegue como esperado. Executando o módulo wallgen diretamente da linha de comando e redirecionando sua saída para um arquivo funciona bem. Meu próximo pensamento é iniciar um processador de comando secundário e iniciar o executável a partir daí ou talvez usar um arquivo em lotes. Ambas as opções são um pouco kludgy Id em vez de saber porque isso não funciona :-) Public Sub Execute () Dim fs Como System. IO. Stream Dim proc Como Novo Processo Dim szResult Como String Dim szPath Como Cadeia GENERATE BALL DATA szPath Me. WorkingDir amp meu. Settings. BallGenResultFile Se Me. KillBeforeExecute exceção em seguida, tentar Kill (szPath) Capturas ex Como arquivo Ignorar FileNotFoundException não encontrado End Try End If fs GetFileStream (My. Settings. BallGenFile) msim. CreateBallGenFile (fs) proc. StartInfo. FileName meu. Settings. BallGenExec proc. StartInfo. WorkingDirectory Me. WorkingDir proc. StartInfo. UseShellExecute Falso proc. StartInfo. CreateNoWindow Verdadeiro proc. StartInfo. RedirectStandardOutput Verdadeiro proc. Start () If Not proc. WaitForExit (My. Settings. BallGenTimeout) Em seguida, proc. Kill () Lança Nova MsExecuteException (My. Settings. BallGenModule, quotTimeout esperando BallGen para terminar executionquot) End If Se corda pare (szResult. Trim, meu. Settings. BallGenNormalExit. Trim, True) ltgt 0 Then Jogue New MsExecuteException (My. Settings. BallGenModule, szResult) End If se não System. IO. File. Exists (szPath), então jogue New MsExecuteException (My. Settings. BallGenModule, arquivo de resultado quotThe BallGen não foi createdquot) End If BALL GEN SUCESSO GERAR PAREDE DE DADOS szPath Me. WorkingDir amp meu. Settings. WallGenResultFile Se Me. KillBeforeExecute então tente Kill (szPath) Capturas ex Como arquivo Ignorar FileNotFoundException não encontrado exceção, jogue todas as outras exceções End Try End If fs GetFileStream (My. Settings. WallGenFile) msim. CreateWallGenFile (fs ) proc Novo Processo proc. StartInfo. FileName meu. Settings. WallGenExec proc. StartInfo. CreateNoWindow Verdadeiro proc. StartInfo. WorkingDirectory Me. WorkingDir proc. StartInfo. UseShellExecute Falso proc. StartInfo. RedirectStandardOutput Verdadeiro proc. StartInfo. RedirectStandardError Verdadeiro proc. Start ( ) If Not proc. WaitForExit (My. Settings. WallGenTimeout) Então proc. Kill () Lança Nova MsExecuteException (My. Settings. WallGenModule, quotTimeout esperando WallGen para terminar executingquot) End If szResult proc. StandardOutput. ReadToEnd If Not System. IO. File. Exists (szPath) Então jogue New MsExecuteException (My. Settings. WallGenModule, arquivo de resultado quotThe WallGen não foi createdquot) End If PAREDE GEN SUCESSO End Sub terça - feira, fevereiro 2, 2010 17:14 Você está caindo em uma armadilha que É documentado - chamar WaitForExit antes ReadToEnd. Sugiro que você leia a seção de observações da propriedade Process. StandardOuput: quot condição de deadlock pode resultar se o pai processo chama p. WaitForExit antes p. StandardOutput. ReadToEnd eo processo filho grava texto suficiente para preencher o fluxo redirecionado. O processo pai esperaria indefinidamente para o processo filho para sair. O processo filho iria esperar indefinidamente para o pai para ler o fluxo completo StandardOutput. quot Aqui está a documentação. Também contém informações sobre como evitar esta situação. HTH Tom Shelton Proposta como resposta por Cor Ligthert MVP Terça-feira, 02 de fevereiro de 2010 18:06 Marcado como resposta por MartinXie Moderador segunda-feira, 08 de fevereiro de 2010 3:12 Terça-feira, 02 de fevereiro de 2010 17:30 Bem-vindo ao MSDN forums Isso ajuda Se você tiver outras dúvidas ou preocupações, não hesite em nos informar. Além disso, aqui está um artigo que demonstra: Como redirecionar Entrada-Saída Padrão de um aplicativo no. NET codeproject / KB / cs / ProcessStartDemo. aspx Obrigado a todos por sua ajuda e suporte amigável. Se você tiver algum feedback sobre o nosso suporte, entre em contato com msdnmgmicrosoft Lembre-se de marcar as respostas como respostas, se eles ajudam e desmarcar-los se eles não fornecem nenhuma ajuda. Bem-vindo ao All-In-One Code Framework. Se você tiver algum comentário, por favor, diga-nos. Sexta-feira, 05 de fevereiro de 2010 9: 35 AMSystem. Diagnostics. Process: redirecionar StandardInput, StandardOutput, StandardError 82218217 InputAndOutputToEnd: uma maneira prática de usar redirecionado entrada / saída / erro em um p. 82218217 ltparam name8221p8221gtP para redirecionar. Deve ter UseShellExecute definido como false. lt/paramgt 82218217 ltparam name8221StandardInput8221gtEssa string será enviada como entrada para o p. (Deve ser Nothing se não StartInfo. RedirectStandardInput) lt / paramgt 82218217 ltparam name8221StandardOutput8221gtA saída p8217s será coletada nesta seqüência ByRef. (Deve ser nada se não StartInfo. RedirectStandardOutput) lt / paramgt 82.218.217 ltparam name8221StandardError8221gtThe p8217s erro será coletado nessa cadeia ByRef. (Deve ser nada se não StartInfo. RedirectStandardError) função lt / paramgt 82218217 ltremarksgtThis resolve o problema de impasse mencionado no msdn. microsoft/en-us/library/system. diagnostics. p.standardoutput. aspxlt/remarksgt ltRuntimepilerServices. Extension () gt Sub InputAndOutputToEnd (ByVal p Como Diagnostics. Process, ByVal standardInput As string. ByRef StandardOutput As string. ByRef StandardError As string) Se p é nada Então jogue New ArgumentException (8220p deve ser não-null8221) 8216 Suponha p começou. Infelizmente não há maneira de verificar. Se p. StartInfo. UseShellExecute Então jogue New ArgumentException (8220Set StartInfo. UseShellExecute para false8221) Se (p. StartInfo. RedirectStandardInput ltgt (standardInput IsNot Nothing)) Em seguida, jogue New ArgumentException (8220Provide uma entrada não nula somente quando StartInfo. RedirectStandardInput8221) Se (p. StartInfo. RedirectStandardOutput ltgt (StandardOutput IsNot Nothing)) em seguida, jogue New ArgumentException (8220Provide uma saída não-nula somente quando StartInfo. RedirectStandardOutput8221) Se (p. StartInfo. RedirectStandardError ltgt (StandardError IsNot Nothing)) em seguida, jogue New ArgumentException (8220Provide Um erro não nulo somente quando StartInfo. RedirectStandardError8221) Dim outputData como novo InputAndOutputToEndData Dim errorData como novo InputAndOutputToEndData Se p. StartInfo. RedirectStandardOutput Then

No comments:

Post a Comment