Friday, 20 October 2017

Process Readtoend Waitforexit


O código parece quase que este: Como você pode ver, o código inicia um processo cmd. exe e passa para ele o comando que eu quero ser executado. Eu redireccionar StandardError e StandarOutput para lê-los a partir do código. O código lê-los antes do processo. WaitForExit (Timeout) chamar conforme recomendado pela Microsoft (mais sobre isso mais tarde). O problema surge se o comando que eu enviar para cmd. exe nunca termina ou trava indefinidamente. No código eu usei o comando ping - t 8.8.8.8 que, por causa da opção - t, pings o host sem parar. O que acontece O processo cmd. exe junto com o comando ping - t nunca sai e nunca fecha o fluxo stdout e assim o nosso código trava na linha Output. StandardOutput. ReadToEnd () porque não consegue ler todos os fluxos. O mesmo acontece também se um comando em um arquivo em lotes trava por qualquer motivo e, portanto, o código acima poderia trabalhar continuamente por anos e, em seguida, pendurar de repente sem qualquer razão aparente. Antes de eu escrever que seu recomendado para ler fluxos redirecionados antes do processo. WaitForExit (Timeout) chamada, bem isso é especialmente verdadeiro se você usar a assinatura WaitForExit sem o tempo limite. Se você chamar o processo. WaitForExit () antes de ler os fluxos redirecionados: código 2: você pode enfrentar um deadlock se o comando que você anexar ao cmd. exe ou o processo que você está chamando preenche a saída padrão ou erro padrão. Isso porque o nosso código não pode alcançar o processo de saída de linhas. StandardOutput. ReadToEnd () Como uma questão de fato o processo filho (o comando ping ou um arquivo em lotes ou qualquer processo que você está executando) não pode ir se o nosso programa não lê os buffers cheios dos fluxos e isso não pode acontecer porque o código está pendurado em A linha com o processo. WaitForExit () que irá esperar para sempre para o projecto filho para sair. O tamanho padrão de ambos os streams é 4096 bytes. Você pode testar esses dois tamanhos com esses arquivos em lote: O primeiro script grava 4096 bytes na saída padrão e o segundo no erro padrão. Salve um desses em C: testbuffsize. bat e execute o nosso processo de chamada de programa. WaitForExit () antes de processo de saída. StandardOutput. ReadToEnd () como no código 2. você pode fazê-lo escrevendo CommandResult Resultado ExecuteShellCommandSync (c: testbuffsize. bat, 1000) na linha 13 do código 1. O código não vai cair, mas se você escrever mais um byte em qualquer uma das duas correntes ele irá transbordar o tamanho do buffer tornando o programa aguentar. Se você precisa redirecionar e ler a saída padrão ou erro standar a melhor solução é lê-los de forma assíncrona. Uma excelente maneira de fazer isso é proposta por Mark Byers neste thread stackoverflow Como a última coisa, observe que se o processo filho sai apenas porque você usa o processo. WaitForExit (Timeout) assinatura e ele realmente vai em timeout você deve matar o processo cmd. exe e suas possíveis crianças. Sua solução não precisa AutoResetEvent mas você pesquisa. Quando você faz pesquisa em vez de usar o evento (quando eles estão disponíveis), então você está usando CPU sem razão e que indicam que você é um programador ruim. Sua solução é realmente ruim quando comparado com o outro usando AutoResetEvent. (Mas eu não te dei -1 porque você tentou ajudar). Ndash Eric Ouellet Nov 7 14 at 18:38 Eu estava tendo o mesmo problema, mas a razão era diferente. No entanto, 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. Eu agora recebi uma janela popup Shell, que é indesejável, mas muito melhor do que o programa esperando nada particular acontecer. Então eu adicionei o seguinte work-around para que: Agora, a única coisa que me incomoda é por que isso está acontecendo no Windows 8 em primeiro lugar. respondeu 13 de janeiro 15 às 10:35 Exemplo de uso ImplementationSystem. Diagnostics. Process: redirecionar standardInput, StandardOutput, StandardError 82.218.217 InputAndOutputToEnd: uma maneira prática de utilizar redirecionada de 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 nada se não StartInfo. RedirectStandardInput) lt / paramgt 82.218.217 ltparam name8221StandardOutput8221gtThe p8217s saída será coletado nessa cadeia 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