Skip to main content

15 C # Processo Waitforexit


O código parece quase isso: como você pode ver, o código inicia um processo cmd. exe e passa para ele o comando que quero ser executado. Eu redireciono StandardError e StandarOutput para lê-los a partir do código. O código lê-los antes do processo. WaitForExit (Timeout) chamada conforme recomendado pela Microsoft (mais sobre isso mais tarde). O problema surge se o comando que eu envio 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 juntamente com o comando ping - t nunca sai e nunca fecha o fluxo de stdout e, portanto, o nosso código trava na linha Output. StandardOutput. ReadToEnd () do processo de saída porque não conseguiu ler todo o fluxo. O mesmo acontece também se um comando em um arquivo em lotes trava por qualquer motivo e, portanto, o código acima pode funcionar continuamente durante anos e, em seguida, é suspenso repentinamente sem nenhum motivo aparente. Antes de escrever, recomendava ler fluxos redirecionados antes do processo. WaitForExit (Timeout), bem, isso é especialmente verdadeiro se você usar a assinatura WaitForExit sem o tempo limite. Se você chamar processo. WaitForExit () antes de ler os fluxos redirecionados: código 2: você pode enfrentar um impasse se o comando que você anexar ao cmd. exe ou o processo que você está chamando preencher a saída padrão ou erro padrão. Isso porque nosso código não pode atingir as linhas de processo de saída. StandardOutput. ReadToEnd () De fato, o processo filho (o comando ping ou um arquivo em lote ou o processo que estiver executando) não pode continuar se o nosso programa não lê os buffers preenchidos dos fluxos e isso não pode acontecer porque o código está pendurado em A linha com o processo. WaitForExit () que aguardará para sempre que o projeto filho saia. O tamanho padrão de ambos os fluxos é de 4096 bytes. Você pode testar esses dois tamanhos com esses arquivos em lote: o primeiro script escreve 4096 bytes para a saída padrão e o segundo para erro padrão. Salve um destes em C: testbuffsize. bat e execute o processo de chamada do nosso programa. WaitForExit () antes do 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 irá pendurar, mas se você escrever um byte mais em qualquer um dos dois fluxos, ele irá transbordar o tamanho do buffer tornando o programa aguentar. Se você precisa redirecionar e ler a saída padrão ou o erro padrão, a melhor solução é lê-los de forma assíncrona. Uma excelente maneira de fazer isso é proposta por Mark Byers neste segmento stackoverflow. Como a última coisa, observe que, se o processo filho sair apenas porque você usa o processo. WaitForExit (Timeout) assinatura e ele realmente vai no tempo limite, você deve matar o processo cmd. exe e seus possíveis filhos. Estou escrevendo um programa que inicia um número desconhecido de processos em sequência usando myProcess. Start () e myProcess. WaitForExit (). O problema parece ser que alguns processos podem iniciar outros processos e, em seguida, sair, fazendo com que meu programa continue sem o processo iniciado, na verdade, completando sua tarefa. Existe alguma maneira de monitorar esses quotsub-processesquot Obrigado de antemão Editar: depois de alguns testes adicionais, descobri que o mesmo problema ocorre quando, por exemplo, iniciando o Winword. exe. WaitForExit simplesmente não funciona com alguns aplicativos. Tom escreveu sobre o mesmo problema neste tópico, mas ficou satisfeito quando trabalhou em um computador diferente. Parece que um processo quotWINWORD. EXEquot já está sendo executado na minha máquina. Possivelmente porque eu uso o Word como editor de e-mail (). Fechando isto antes de executar meu programa (que está configurado para iniciar a palavra e aguardar a saída) quotsolvesquot o problema. No entanto, eu não posso assumir que winword não está sendo executado quando o meu programa é iniciado. Quinta-feira, 09 de agosto de 2007 8:01 am Não, não há muito que você possa fazer de forma confiável. O problema é que, no momento em que você chama WaitForExit, o aplicativo talvez já tenha iniciado outro aplicativo e tenha saído não há como saber se esse aplicativo gerou outras pessoas nesse ponto. É a natureza do Process. Start. Você não está descobrindo que WaitForExit espera indefinidamente porque o processo veio e foi antes de você chamar você é quinta-feira, 09 de agosto de 2007 1:15 PM Bem, ele cria um novo processo, é tão rápido que não pode aparecer em processo Explorador. Todo Process. Start faz é pedir ao processo para iniciar não há nada mais que o novo processo é obrigado a fazer. Se não quer ficar na memória, essa é a escolha. Não há nada que você possa fazer sobre isso, infelizmente. Algumas aplicações sempre iniciam um novo processo. Quando você abre um arquivo Visual Studio SLN, por exemplo, ele sempre inicia dois processos. Existe uma pequena aplicação que verifica o tipo de arquivo SLN e, em seguida, abre uma versão apropriada do Visual Studio porque você só pode associar uma aplicação por extensão. A outra questão é que algumas aplicações podem lidar com vários documentos de cada vez, o que significa que eles geralmente reutilizam os processos existentes. Em casos como este, se o processo for reutilizado porque um documento já estava aberto, isso significa que o documento que você abriu com Process. Start pode ser fechado, mas o processo de hospedagem ainda está sendo executado (atendendo o documento original), o que significa que você nunca pode Diga quando o processo que foi reutilizado quando você chamou Process. Start é feito com o documento que foi aberto com seu Process. Start. Se você quiser integrar algum tipo de solução do WinWord, eu sugiro usar a automação. Consulte msdn. microsoftnewsgroupsdefault. aspxdgmicrosoft. public. officedevamplangenampcrUS para discussões sobre a automação de produtos do Office. Quinta-feira, 09 de agosto de 2007 13:37 Você precisaria acompanhar quantos processos foram lançados e usá-lo em sua lógica. Você também pode usar o WaitForMultipleObjects se você souber de antemão, aproximadamente, quantos processos serão iniciados. O tempo que um processo inicia, o processo bloqueia um objeto e incrementa o contador. Sempre que o processo termina, bloqueia o objeto e diminui o contador. Quando o processo foi disparado x quantidade de vezes, foi solicitado a esperar que ele acordasse, bloqueia o objeto e verifica para ver quantos objetos estão lá e que espera por esse número de objetos novamente. Quinta-feira, 09 de agosto de 2007 12:39 PM Não, não há muito o que você pode fazer de forma confiável. O problema é que, no momento em que você chama WaitForExit, o aplicativo talvez já tenha iniciado outro aplicativo e tenha saído não há como saber se esse aplicativo gerou outras pessoas nesse ponto. É a natureza do Process. Start. Você não está achando que WaitForExit espera indefinidamente porque o processo veio e foi antes de você chamar você é quinta-feira, 09 de agosto de 2007 1:15 PM Não, eu espero que a situação não ocorra (É mesmo possível que Havent pensou antes). . De qualquer forma, isso responde claramente a um dos problemas. Obrigado. Mas deve haver uma súbita questão sobre o início do winword. exe (e similar) que. Nenhum processo extra é mostrado no taskmanager (mas ainda a palavra aparece). Quero forçar a criação de um novo processo que eu possa controlar. Quinta-feira, 09 de agosto de 2007 1:25 PM Bem, ele cria um novo processo, é tão rápido que não pode aparecer no Process Explorer. Todo Process. Start faz é pedir ao processo para iniciar não há nada mais que o novo processo é obrigado a fazer. Se não quer ficar na memória, essa é a escolha. Não há nada que você possa fazer sobre isso, infelizmente. Algumas aplicações sempre iniciam um novo processo. Quando você abre um arquivo Visual Studio SLN, por exemplo, ele sempre inicia dois processos. Existe uma pequena aplicação que verifica o tipo de arquivo SLN e, em seguida, abre uma versão apropriada do Visual Studio porque você só pode associar uma aplicação por extensão. A outra questão é que algumas aplicações podem lidar com vários documentos de cada vez, o que significa que eles geralmente reutilizam os processos existentes. Em casos como este, se o processo for reutilizado porque um documento já estava aberto, isso significa que o documento que você abriu com Process. Start pode ser fechado, mas o processo de hospedagem ainda está sendo executado (atendendo o documento original), o que significa que você nunca pode Diga quando o processo que foi reutilizado quando você chamou Process. Start é feito com o documento que foi aberto com seu Process. Start. Se você quiser integrar algum tipo de solução do WinWord, eu sugiro usar a automação. Consulte msdn. microsoftnewsgroupsdefault. aspxdgmicrosoft. public. officedevamplangenampcrUS para discussões sobre a automação de produtos do Office. Quinta-feira, 09 de agosto de 2007 1:37 PM Bem, é verdade que o enquadramento não permite encontrar os subprocessos diretamente, algo pode ser combinado. Você pode obter o Pid do processo que você iniciou e, em seguida, usando o PInvoke, você pode descobrir o Pid principal de todos os processos em execução e compará-los. Você pode esperar por essas sub preocupações para sair. Aqui está um exemplo de C usando a API. Você gostaria de procurar algo como Pinvoke para como convertê-lo quinta-feira, 09 de agosto de 2007 16:20 A Microsoft está realizando uma pesquisa on-line para entender sua opinião sobre o site da Msdn. Se você optar por participar, a pesquisa on-line será apresentada quando você deixar o site Msdn. Você gostaria de participar do processo. WaitForExit Method () WaitForExit () faz o thread atual aguardar até o processo associado terminar. Ele deve ser chamado após todos os outros métodos serem chamados no processo. Para evitar o bloqueio da linha atual, use o evento Exitado. Este método instrui o componente Processo a aguardar uma quantidade infinita de tempo para que o processo e os manipuladores de eventos saem. Isso pode fazer com que um aplicativo pare de responder. Por exemplo, se você chamar CloseMainWindow para um processo que tenha uma interface de usuário, a solicitação ao sistema operacional para encerrar o processo associado pode não ser tratada se o processo for gravado para nunca entrar no loop de mensagem. No Quadro 3.5 e versões anteriores, a sobrecarga WaitForExit () esperava milissegundos MaxValue (aproximadamente 24 dias), não indefinidamente. Além disso, as versões anteriores não esperaram que os manipuladores de eventos saíssem se o tempo MaxValue completo fosse atingido. Essa sobrecarga garante que todo o processamento foi concluído, incluindo o tratamento de eventos assíncronos para a 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. Quando um processo associado sai (ou seja, quando é encerrado pelo sistema de operação através de um término normal ou anormal), o sistema armazena informações administrativas sobre o processo e retorna ao componente que chamou WaitForExit (). O componente Processo pode acessar a informação, que inclui o ExitTime. Usando o Handle para o processo encerrado. Como o processo associado saiu, a propriedade Handle do componente já não aponta para um recurso de processo existente. Em vez disso, o identificador pode ser usado apenas para acessar a informação dos sistemas operacionais sobre o recurso do processo. O sistema está ciente das alças para os processos que não foram lançados pelos componentes do Processo, portanto, mantém as informações ExitTime e Handle na memória até que o componente Processo liberte especificamente os recursos. Por esse motivo, sempre que ligar a instância do Começo para um processo, chame Close quando o processo associado tiver terminado e você não precisa mais de informações administrativas sobre isso. Fechar libera a memória alocada para o processo encerrado. Leia o que MSDN diz sobre isso: A sobrecarga WaitForExit () () () é usada para fazer o segmento atual aguardar até o processo associado terminar. Este método instrui o componente Processo a aguardar uma quantidade infinita de tempo para que o processo saia. Isso pode fazer com que um aplicativo pare de responder. Por exemplo, se você chamar CloseMainWindow para um processo que tenha uma interface de usuário, a solicitação ao sistema operacional para encerrar o processo associado pode não ser tratada se o processo for gravado para nunca entrar no loop de mensagem. Essa sobrecarga garante que todo o processamento foi concluído, incluindo o tratamento de eventos assíncronos para a 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. Isso é, naturalmente, para. O que faz você pensar que não aguarda que o processo Note termine. Quais são os sinais disso. Qual é a prova sexta-feira, 20 de fevereiro de 2009 8:13 PM Não tenho certeza se isso mudou recentemente, mas de volta no dia aplicações na janela O celular nunca foi realmente fechado quando bateu no X para fechá-los, eles apenas minimizariam e continuavam funcionando em segundo plano (isso não era um bug, era um recurso, já que da próxima vez que você iniciar o aplicativo, ele seria iniciado com muita rapidez, yah Eu sei, insano, mas verdadeiro), então, por isso, o WaitForExit talvez esteja se comportando estranhamente e aguardando a inicialização do aplicativo em vez de sair. Mas, novamente, é apenas uma especulação baseada em conhecimentos de versões antigas do Windows Mobile. Sexta-feira, 20 de fevereiro de 2009 11:03 PM Eu gostaria de colidir esta questão. Estou no Windows Mobile 6 Standard e estou tentando gerar uma instância do navegador. Gostaria de aguardar até o usuário fechar o navegador. Mas WaitForExit retorna extremamente rápido. Aqui está o código: Processo p novo Processo () p. StartInfo. Argumentos quotexample-sitequot p. StartInfo. Verb quotOpenquot p. StartInfo. UseShellExecute falso p. StartInfo. FileName quotIExplore. exequot p. Start () p. WaitForExit () MessageBox. Show (quotNow o navegador deve ser closedquot) Qual deve ser o caminho certo para obter os reencontros esperados Segunda-feira, 08 de junho de 2009 22:45 Onde está o símbolo. símbolo. AlexB Terça, 09 de junho de 2009 9:58 PM Estou vendo o mesmo problema, mas no XP. Eu acho que a prova pode ser vista em qualquer depurador (como estou vendo), ou em qualquer aplicativo de console (não necessariamente no celular) quarta-feira, 02 de setembro de 2009 8:35 PM Exceto que você não obtém um objeto de processo que você pode usar. Se você tentar DimProjetos NovosProcessos () myProc Process. Start (quotiexplorequot, quotfinance. yahooqhpsquot symbol) myProc. WaitForExit () Ele ainda retorna imediatamente. Quarta-feira, 2 de setembro de 2009 8:48 PM O problema é que você não está iniciando uma nova instância de iexplore. exe. Você está apenas criando uma nova janela no processo existente. O meu palpite é que iexplore. exe começa, vê uma instância anterior e se comunica com a instância anterior para que ela abre a nova janela, e então essa instância que você iniciou sai imediatamente. Portanto, o comportamento é correto e esperado. Blog. voidnish quarta-feira, 2 de setembro de 2009 8:52 PM A Microsoft está realizando uma pesquisa on-line para entender sua opinião sobre o site da Msdn. Se você optar por participar, a pesquisa on-line será apresentada quando você deixar o site Msdn. Você gostaria de participar

Comments