Monday 2 April 2018

Saída padrão c waitforexit


O código se parece com quase isso: como você pode ver, o código inicia um processo cmd. exe e passa para ele o comando que eu quero executar. Eu redireciono StandardError e StandarOutput para lê-los a partir do código. O código os lê antes do processo. WaitForExit (Tempo limite) chamada 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, faz pings no 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, portanto, o nosso código trava na linha Saída do processo. StandardOutput. ReadToEnd () porque não consegue ler 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. Antes de eu escrever que é recomendado ler fluxos redirecionados antes do processo. Chamada WaitForExit (Timeout), bem, isso é especialmente verdadeiro se você usar a assinatura WaitForExit sem o tempo limite. Se você ligar para o processo. WaitForExit () antes de ler os fluxos redirecionados: código 2: você pode experimentar um deadlock se o comando anexado ao cmd. exe ou o processo que você está chamando preencher a saída padrão ou o erro padrão. Isso porque o nosso código não pode alcançar o processo de saída de linhas. StandardOutput. ReadToEnd () Na verdade, o processo filho (o comando ping ou um arquivo em lote ou qualquer outro processo que você esteja executando) não pode ser executado se nosso programa não ler os buffers preenchidos dos streams e isso não acontecer porque o código está travado a 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: 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 nosso processo de chamada de programa. WaitForExit () antes do processo de saída. StandardOutput. ReadToEnd () como no código 2. você pode fazer isso escrevendo CommandResult Resultado ExecuteShellCommandSync (c: testbuffsize. bat, 1000) na linha 13 do código 1. O código não irá travar, mas se você escrever mais um byte em qualquer um dos dois fluxos ele irá estourar o tamanho do buffer tornando o programa aguentar. Se você precisar redirecionar e ler a saída padrão ou o erro padrão, a melhor solução é lê-los de forma assíncrona. Uma maneira excelente de fazer isso é proposta por Mark Byers neste thread de stackoverflow. Como a última coisa, por favor note que se o processo filho sair apenas porque você usa o processo. WaitForExit (Timeout) assinatura e realmente vai em tempo limite você deve matar o processo cmd. exe e seus possíveis filhos. tenho um aplicativo que chama outro processo em uma janela de comando e esse processo tem estatísticas de atualização que a saída para a janela do console. Eu pensei que esta era uma operação bastante simples, mas eu não consigo fazê-lo funcionar. Estou faltando alguma coisa? Idealmente, o que eu gostaria é que, à medida que a saída muda dentro desse processo, eu acerte ou os dados entrem no leitor, de modo a obter eventos. Qualquer ajuda seria ótima, eu sinto que esta é uma pergunta de novato, mas parece estar faltando alguma coisa. perguntou Jul 17 09 at 22:33 Eu já experimentei isso antes. Às vezes, a maneira em que o processo que você está chamando saídas para o console não é compatível com esse tipo de redirecionamento de saída. Tenho tido a sorte, nesse caso, de poder modificar o processo externo para contornar isso. Você pode tentar executar seu código em outro processo que é enviado para o console e ver se ele funciona corretamente. Ele lê sobre direito para mim agora. Eu fui e puxei um bloco de código que eu usei para fazer isso. Isso está em um aplicativo WPF que redireciona a saída do processo para a janela. Observe a ligação do evento. Como esse é o WPF, tenho que invocar minha chamada para gravar os dados. Uma vez que você não está preocupado com o bloqueio, deve ser capaz de simplesmente substituir isso por: Espero que ajude Curiosamente você não pode ler a saída padrão e o erro padrão ao mesmo tempo: se você redirecionar a saída padrão e o erro padrão e tentar ler os dois , por exemplo, usando o seguinte código C. string output p. StandardOutput. ReadToEnd () string error p. StandardError. ReadToEnd () Nesse caso, se o processo filho grava qualquer texto em erro padrão, ele irá bloquear o processo, porque o processo pai não pode ler do erro padrão até que tenha terminou de ler a partir da saída padrão. No entanto, o processo pai não lerá da saída padrão até o processo terminar. Uma solução recomendada para essa situação é criar dois segmentos para que seu aplicativo possa ler a saída de cada fluxo em um thread separado. Leia o que o MSDN diz sobre ele: A sobrecarga WaitForExit () () () é usada para fazer a corrente thread aguarde até que o processo associado termine. Este método instrui o componente Process a aguardar uma quantidade infinita de tempo para o processo sair. Isso pode fazer com que um aplicativo pare de responder. Por exemplo, se você chamar CloseMainWindow para um processo que tenha uma interface com o usuário, a solicitação para o sistema operacional finalizar o processo associado poderá não ser tratada se o processo for gravado para nunca inserir seu loop de mensagem. Essa sobrecarga assegura que todo o processamento tenha sido 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 tiver sido redirecionada para manipuladores de eventos assíncronos. Isso é claro para o. NET. O que faz você pensar que não espera que o processo de anotação termine Quais são os sinais disso? Qual é a prova sexta-feira, 20 de fevereiro de 2009 20:13 Não tenho certeza se isso mudou recentemente, mas de volta ao dia os aplicativos na janela mobile nunca realmente fechado quando você aperta o X para fechá-los, eles apenas minimizam e continuam rodando em segundo plano (isso não foi um bug, foi um recurso, já que da próxima vez que você iniciar o app ele seria iniciado muito rápido, yah Eu sei, insano, mas é verdade), então pode ser por isso que o WaitForExit está se comportando de forma estranha e aguardando a inicialização do aplicativo em vez da saída. mas, novamente, é apenas especulação baseada no conhecimento de versões antigas do Windows Mobile. Sexta-feira, 20 de fevereiro de 2009 23:03 Eu gostaria de colocar essa questão em ordem. Estou no Windows Mobile 6 Standard e estou tentando gerar uma instância do navegador. Id gostaria de esperar até que o usuário feche o navegador. Mas WaitForExit retorna extremamente rápido. Aqui está o código: Processo p novo Process () p. StartInfo. Arguments quotexample-sitequote p. StartInfo. Verb quotOpenquot p. StartInfo. UseShellExecute falso p. StartInfo. FileName quotIExplore. exequot p. Start () p. WaitForExit () MessageBox. Show (quotNow o navegador deve ser fechado) O que deve ser o caminho certo para obter os resultados esperados Segunda, 8 de Junho de 2009 22: 45 Onde o símbolo está. símbolo. AlexB Terça-feira, 9 de junho de 2009 21:58 Estou vendo o mesmo problema, mas no XP. Eu acho que a prova pode ser vista em qualquer depurador (como eu estou vendo), ou em qualquer aplicativo de console (não necessariamente no celular) Quarta-feira, 02 de setembro de 2009 20:35 Exceto que você não, em seguida, obter um objeto de processo que você pode usar. Se você tentar Dim myProc como novo processo () myProc Process. Start (quotiexplorequot, quotfinance. yahoo/q/hpsquot símbolo) myProc. WaitForExit () Ele ainda retorna imediatamente. Quarta-feira, 2 de setembro de 2009 20:48 Problema é que você não está iniciando uma nova instância do iexplore. exe. Você está apenas criando uma nova janela no processo existente. Meu palpite é que o iexplore. exe inicia, vê uma instância anterior e se comunica com a instância anterior para que abra a nova janela e, em seguida, essa instância iniciada sai imediatamente. Portanto, o comportamento está correto e é esperado. A Microsoft está realizando uma pesquisa online para entender sua opinião sobre o site da MSDN. Se você optar por participar, a pesquisa on-line será apresentada quando você sair do site do Msdn. Você gostaria de participar

No comments:

Post a Comment