Waitforexit c #
Obter através da App Store Leia esta publicação em nosso aplicativo!
Aguarde até um processo terminar.
Eu tenho um aplicativo que faz.
para iniciar outro aplicativo 'ABC'. Eu quero aguardar até que o aplicativo final (processo morre) e continuar minha execução. Como eu posso fazer isso?
Pode haver várias instâncias do aplicativo 'ABC' executando ao mesmo tempo.
Eu acho que você só quer isso:
Consulte a página MSDN para o método. Também tem uma sobrecarga onde você pode especificar o tempo limite, então você não está esperando potencialmente para sempre.
Use Process. WaitForExit? Ou assine o evento Process. Exited se você não quer bloquear? Se isso não fizer o que você quer, por favor nos dê mais informações sobre seus requisitos.
Faço o seguinte na minha aplicação:
Há alguns recursos extras lá que você pode achar úteis.
Você pode usar a espera para sair ou você pode pegar a propriedade HasExited e atualizar sua UI para manter o usuário "informado" (gerenciamento de expectativa):
Exemplo de uso.
Resolvi assim:
Eu redirecionava a entrada, a saída e o erro e administrai a leitura dos fluxos de saída e erro. Esta solução funciona para o SDK 7- 8.1, tanto para o Windows 7 como para o Windows 8.
Eu tentei fazer uma aula que resolva seu problema usando a leitura de fluxo assíncrono, levando em conta Mark Byers, Rob, Stevejay responde. Ao fazê-lo, percebi que existe um erro relacionado à leitura assíncrona do fluxo de saída do processo.
Você não pode fazer isso:
Você receberá System. InvalidOperationException: StandardOut não foi redirecionado ou o processo ainda não começou.
Então, você deve iniciar a saída assíncrona lida após o processo ser iniciado:
Fazendo isso, faça uma condição de corrida porque o fluxo de saída pode receber dados antes de configurá-lo como assíncrono:
Então algumas pessoas podem dizer que você só precisa ler o fluxo antes de configurá-lo como assíncrono. Mas o mesmo problema ocorre. Haverá uma condição de corrida entre a leitura síncrona e configurará o fluxo em modo assíncrono.
Não há como conseguir uma leitura assíncrona segura de um fluxo de saída de um processo na forma real "Processo" e "ProcessStartInfo" foi projetado.
Você provavelmente está melhor usando a leitura assíncrona, como sugerido por outros usuários para o seu caso. Mas você deve estar ciente de que você pode perder algumas informações devido à condição de corrida.
Nenhuma das respostas acima está fazendo o trabalho.
A solução Rob trava e a solução 'Mark Byers' obtém a exceção descarta. (Eu tentei as "soluções" das outras respostas).
Então eu decidi sugerir outra solução:
Este código é depurado e funciona perfeitamente.
Eu acho que isso é uma abordagem simples e melhor (não precisamos do AutoResetEvent):
Eu estava tendo o mesmo problema, mas a razão era diferente. No entanto, isso 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. Agora recebi uma janela popup do Shell, que é indesejável, mas muito melhor do que o programa esperando que nada de particular aconteça. Então eu adicionei o seguinte trabalho para isso:
Agora, o único problema que me incomoda é o porquê isso está acontecendo no Windows 8, em primeiro lugar.
Introdução.
A resposta atualmente aceita não funciona (lança exceção) e há muitas soluções alternativas, mas nenhum código completo. Isso é, obviamente, desperdiçando muito tempo das pessoas porque esta é uma questão popular.
Combinando a resposta de Mark Byers e a resposta de Karol Tyl, escrevi um código completo baseado em como eu quero usar o método Process. Start.
Eu usei-o para criar um diálogo de progresso em torno dos comandos git. É assim que eu usei isso:
Em teoria, você também pode combinar stdout e stderr, mas não testei isso.
Eu sei que isso é velho, mas, depois de ler toda essa página, nenhuma das soluções estava funcionando para mim, embora eu não tentei Muhammad Rehan porque o código era um pouco difícil de seguir, embora eu acho que ele estava no caminho certo . Quando eu digo que não funcionou, isso não é inteiramente verdade, às vezes funcionaria bem, acho que é algo a ver com a duração da saída antes de uma marca EOF.
De qualquer forma, a solução que funcionou para mim era usar diferentes threads para ler o StandardOutput e StandardError e escrever as mensagens.
Espero que isso ajude alguém, que pensou que isso poderia ser tão difícil!
As outras soluções (incluindo o EM0) ainda estão bloqueadas para o meu aplicativo, devido a tempos de espera internos e ao uso de StandardOutput e StandardError pela aplicação gerada. Aqui está o que funcionou para mim:
Editar: inicialização adicionada de StartInfo para codificar a amostra.
Este post talvez esteja desactualizado, mas descobri a principal causa por que normalmente ele trava é devido ao excesso de pilha para o redirectStandardoutput ou se você tem redirectStandarderror.
Como os dados de saída ou os dados de erro são grandes, isso causará um tempo de espera, pois ele ainda está processando por tempo indefinido.
Waitforexit c #
Esta pergunta pode parecer um pouco estranha, mas estou tentando executar VS2005 através de um processo e executar um comando específico e eu waitforexit (). Estou redirecionando minha entrada e saída com sucesso, mas de vez em quando eu recebo uma Window Window / Message Window Window. O problema é que eu estou remoting, então quando esta mensagem / janela ocorre durante a execução do processo, eu vou pendurar a menos que eu logar na outra máquina (remota) e fechar a janela.
Existe alguma maneira de matar programaticamente esta janela ou possivelmente desativar a mensagem / janela? Eu pensei em executar o VS em uma execução silenciosa (ainda tenho que encontrar uma maneira de fazê-lo). Eu também tentei ver se há algo que está sendo lançado quando isso ocorre comparado ao quando não.
Bem, eu tentei usar FindWindow e FindWindowEx junto com SendMessage, mas não consegui encontrar o identificador de janela correto. Mas, como eu sei que uma caixa de Msssage de relatórios de erros do Windows aparecerá, verifiquei se era seu próprio processo (e é). O processo é dwwin. exe (Dr. Watson Win) e tudo o que eu tinha que fazer era isso para me permitir corrigir o problema atual. Substitua o atual bloco de código abaixo para a declaração WaitForExit () que eu tinha anteriormente.
Proc. WaitForExit (60000); // um minuto.
Processo [] ProcArray = Process. GetProcessesByName (& quot; dildin & quot;);
foreach (Process ProcessFound em ProcArray)
Eu também verifiquei se você conseguiu obter o Process. MainWindowTitle (), mas está definido como & quot; & quot ;. Então, isso é um hack e eu realmente não gosto de usá-lo, mas funciona para a execução atual.
Todas as respostas.
Você pode ser específico com o erro que está recebendo?
Isso ocorre apenas quando você está redirecionando a entrada e a saída?
Você está executando console? Cmd & quot; ?
Se sim, você deve digitar exit também.
// Processo interrompido antes do período de tempo limite.
// Imprimir mensagem de erro?
Gostaria de tentar isso, mas é muito um hack. Eu tenho muitos comandos diferentes que levam diferentes períodos de tempo (30 segundos a 25 minutos), então não há configurações de tempo real que eu poderia colocar sem destruir o meu desempenho. Esta função tem funcionado corretamente para vários comandos nos últimos 6 meses e agora ele decide sair para mim. Eu tentei em um computador diferente sem problemas (o que realmente está me mexendo). Eu sei que não é o redirecionamento de saída / erro porque uma nova WINDOW está sendo criada no servidor ao qual eu estou remoting. Assim que eu fechar essa janela, meu processo sai como esperado e a saída correta é exibida no lado do Usuário.
Obrigado pela sua ajuda, mas estou realmente frustrado com este problema.
Sem saber o detalhe da mensagem, estamos apenas adivinhando o problema.
Você instalou o beta 3.5 beta ou o Visual Studio 2008 beta?
Como você está usando o Processo para iniciar o programa, Process. Start (& quot; file. exe & quot;), ou você está usando ProcessStartInfo?
Não, eu tenho 2003 e 2005 instalados.
proc = new Process ();
procSI = novo ProcessStartInfo ();
Em seguida, configurei um novo tópico para o StandardError e StandardOutput.
Depois escrevo meus comandos e.
se (redirecionando o padrão para fora)
Inicie o tópico para o st. Fora.
Se (redirecionando o erro padrão)
Inicie o tópico para o st. erro.
Proc. WaitForExit (); & lt; -------- é onde ocorre a janela Generic Windows Reporting de Erros.
Eu traduzi o que pude da Janela que aparece.
問題 が 発 生 し た た め, Microsoft Visual Studio 2005 を 終了 し ま す. ご 不便 を お か け し て 申 し 訳 あ り ま せ ん.
Porque o problema ocorre, ele termina o Microsoft Visual Studio 2005. Aplicando inconvenientes, não há desculpa.
Obrigado novamente por todo o seu tempo.
Por que você está fazendo isso? Você não possui esse fluxo, então você não deve fechá-lo.
Isso é um erro de digitação? Antes de você falar sobre uma variável chamada "proc", não "Proc". Então, isso é simplesmente uma referência nula porque você está tentando invocar um método em uma referência diferente de "proc"?
Você não deseja fechar o objeto sIn até que o aplicativo tenha saído se você estiver redirecionando. Se o aplicativo grava a saída padrão ou lê da entrada padrão depois de fechar qualquer um desses, isso pode causar uma exceção.
Você tem o rastreamento da pilha dessa mensagem de erro?
Você não deseja fechar o objeto sIn até que o aplicativo tenha saído se você estiver redirecionando.
Não se deve fechar nenhum desses fluxos. O objeto Processo os possui e é o responsável pela limpeza depois de si próprio. Deveria, na melhor das hipóteses, chamar Process. Dispose () depois de terminar o objeto Processo.
Eu criei o SQL Server do StreamWriter antes de criar o objeto Proc Process. Eu então redireciono a entrada após o comando proc. Start (), então, como eu não possuo isso? Independentemente disso, posso fazer a mudança para mover o sIn. Close () para depois da chamada WaitForExit para ver se isso faz alterações.
O Proc era um tipo, deveria ter sido proc.
Novamente, não é uma mensagem de erro, portanto, não há rastreamento de pilha. O redirecionamento do meu StandardError está vazio eo redirecionamento de saída padrão contém o que eu esperava, mas nada indicando que ocorreu um erro. É por isso que tudo ainda funciona depois que eu fechar a janela de Relatório de Erros do Windows.
Posso publicar o que acontece depois de mover a linha sIn. Close () abaixo da linha WaitForExit ().
Você não deseja fechar o objeto sIn até que o aplicativo tenha saído se você estiver redirecionando.
Não se deve fechar nenhum desses fluxos. O objeto Processo os possui e é o responsável pela limpeza depois de si próprio. Deveria, na melhor das hipóteses, chamar Process. Dispose () depois de terminar o objeto Processo.
Ok, estou fazendo Process. Fechar no último bloco do meu código, então deve ser cuidada então.
Perceba o meu comentário "não próprio" que eu fiz anteriormente. Acabei de voltar de almoço e faltava o fato de que o processo tem controle disso.
Process. Close é o método recomendado para fechar os fluxos de entrada padrão e padrão (e padrão).
Eu ficaria surpreso se o método Dispose não chamasse de Fechar, pelo menos como parte de sua operação. Eu preferiria usar o fato de que, desde que o Processo implementa IDisposable (indiretamente através do componente de extensão que o implementa), um deve invocar Dispose e permitir que a limpeza adequada. Eu não recomendaria invocar Process. Close em vez de, nem além de, Process. Dispose.
Process. Close é o método recomendado para fechar os fluxos de entrada padrão e padrão (e padrão).
Eu ficaria surpreso se o método Dispose não chamasse de Fechar, pelo menos como parte de sua operação. Eu preferiria usar o fato de que, desde que o Processo implementa IDisposable (indiretamente através do componente de extensão que o implementa), um deve invocar Dispose e permitir que a limpeza adequada. Eu não recomendaria invocar Process. Close em vez de, nem além de, Process. Dispose.
Como tenho certeza que você sabe, estes são funcionalmente equivalentes:
usando (SomethingDisposable myObject =.)
// use myObject aqui.
// use myObject aqui.
se (myObject! = null) myObject. Dispose ();
Então, se a primeira recomendação for usar um bloco de uso, então o próximo melhor seria chamar Dispose, não Fechar, quando, como você disse, você sabe que você terminou com o objeto.
Ao ligar apenas perto de algo que implementa IDisposable, o desenvolvedor está cometer um erro. Se Dispose fizer alguma limpeza adicional além de apenas delegar para Fechar, então o programador está configurando-se para um bug, apenas ligando para Fechar.
Pode haver um caso para chamar Close, mas somente se você não tiver terminado com o objeto, como você indicou na parte inferior da sua última resposta. Mas quando terminar com isso, chame Dispose.
Como tenho certeza que você sabe, estes são funcionalmente equivalentes:
usando (SomethingDisposable myObject =.)
// use myObject aqui.
// use myObject aqui.
se (myObject! = null) myObject. Dispose ();
Então, se a primeira recomendação for usar um bloco de uso, então o próximo melhor seria chamar Dispose, não Fechar, quando, como você disse, você sabe que você terminou com o objeto.
Ao ligar apenas perto de algo que implementa IDisposable, o desenvolvedor está cometer um erro. Se Dispose fizer alguma limpeza adicional além de apenas delegar para Fechar, então o programador está configurando-se para um bug, apenas ligando para Fechar.
Pode haver um caso para chamar Close, mas somente se você não tiver terminado com o objeto, como você indicou na parte inferior da sua última resposta. Mas quando terminar com isso, chame Dispose.
DisposableClass obj = new DisposableClass ();
IDisposable descartable = obj como IDisposable;
se (descartável! = nulo)
Mas sim, é isso que uma declaração de uso é "equivalente funcionalmente" para; mas eu não concordo chamando explicitamente Dispose na presença de um & quot; Close & quot; O método deve ser a primeira escolha devido à falta de escopo com a chamada Dispose. Por exemplo, o seguinte:
usando (processo processo = novo processo ()
. é um erro de sintaxe.
Enquanto o seguinte:
Processo process = new Process ();
// não há como garantir o "processo" não vai.
// seja acessado após o acima.
É um erro em tempo de execução (ObjectDisposedException). Usar fechar não causa o erro de tempo de execução:
Processo process = new Process ();
É sempre melhor trocar um erro de tempo de compilação por um erro de tempo de execução.
Então, estabeleci um ponto de interrupção após a chamada proc. WaitForExit () e ainda não atingi este ponto de interrupção. Então parece que é um problema.
Então, estabeleci um ponto de interrupção após a chamada proc. WaitForExit () e ainda não atingi este ponto de interrupção. Então parece que é um problema.
Eu tinha o serviço funcionando, mas eu parei porque tinha funcionado por 2 horas e nunca tinha o ponto de interrupção que deveria ter atingido dentro de 10 minutos de mim, começando meu cliente. Eu não comentei a linha sIn. Close () agora e voltei a iniciar o serviço e o Cliente e tudo está funcionando como antes. Posso acertar o ponto de interrupção após o WaitForExit () e eu concluir, com a mensagem de relatório de erros do Windows ainda (como era antes).
Então, no meu caso, PRECISO fechar o fluxo de entrada para poder sair do processo conforme o esperado. Existem outras idéias?
Eu posso recomendar a linha sIn. Close () se você quiser verificar algo.
Eu tinha o serviço funcionando, mas eu parei porque tinha funcionado por 2 horas e nunca tinha o ponto de interrupção que deveria ter atingido dentro de 10 minutos de mim, começando meu cliente. Eu não comentei a linha sIn. Close () agora e voltei a iniciar o serviço e o Cliente e tudo está funcionando como antes. Posso acertar o ponto de interrupção após o WaitForExit () e eu concluir, com a mensagem de relatório de erros do Windows ainda (como era antes).
Então, no meu caso, PRECISO fechar o fluxo de entrada para poder sair do processo conforme o esperado. Existem outras idéias?
Eu posso recomendar a linha sIn. Close () se você quiser verificar algo.
Como você está usando a entrada padrão e a saída padrão? Você está usando algum método ReadLine?
Peter, meu objetivo é:
Se você não chamar Dispose em um objeto que implemente (diretamente ou indiretamente) IDisposable, então você está apenas pedindo um bug. No entanto, não quero argumentar sobre isso sem parar. Você pode continuar a fazê-lo da maneira que você faz, e eu vou ficar com o meu. Enquanto não tivermos que manter o código de cada um, tudo bem.
E, a propósito, um "uso" de & quot; O bloco também não o protege. Nada impede que você declare a variável fora do bloco (se eu me lembro corretamente), então ainda pode estar no escopo após o fim do bloco. Você precisa ser diligente ao escrever o código correto. Se você declara isso no & quot; usando & quot; declaração, é uma maneira. Mas descartar o uso da abordagem try / finally apenas porque deixa a variável no escopo não é realmente o ponto. Ainda precisa ser Dispose () 'D em algum lugar.
Eu tinha o serviço funcionando, mas eu parei porque tinha funcionado por 2 horas e nunca tinha o ponto de interrupção que deveria ter atingido dentro de 10 minutos de mim, começando meu cliente. Eu não comentei a linha sIn. Close () agora e voltei a iniciar o serviço e o Cliente e tudo está funcionando como antes. Posso acertar o ponto de interrupção após o WaitForExit () e eu concluir, com a mensagem de relatório de erros do Windows ainda (como era antes).
Então, no meu caso, PRECISO fechar o fluxo de entrada para poder sair do processo conforme o esperado. Existem outras idéias?
Eu posso recomendar a linha sIn. Close () se você quiser verificar algo.
Como você está usando a entrada padrão e a saída padrão? Você está usando algum método ReadLine?
Mais uma vez, NÃO É uma Exceção que está sendo jogada, então não vejo detalhes de exceção. Eu não vou diretamente para o bloco catch no meu código, eu retomo DIRECTAMENTE após a chamada WaitForExit (). A janela que recebo é a mesma que você obtém quando CADA produto da Microsoft fecha inesperadamente e MS quer informações sobre o Crash. Então, novamente, não há detalhes de exceção. No entanto, em um dos logs do sistema, estou recebendo uma mensagem (traduzido do japonês)
"Erros de aplicação Devenv. exe ocorrem, 8.0.50727.762 versão dos erros ocorridos módulo msvcr80.dll, versão 8.0.50727.762, erro ocorreu endereço 0x00039001.
Para obter mais informações, go. microsoft/fwlink/events. asp o Helo e o Centro de suporte, por favor consulte. & Quot;
Estou redirecionando a entrada padrão para passar nos diferentes comandos, porque eu estava tendo problemas para fazê-los funcionar como queria formar o StartInfo. Estou redirecionando os fluxos de Saída e Erro para verificar o que eles têm neles depois que o processo foi encerrado. Isso me permitirá verificar qualquer coisa que eu gostaria em qualquer fluxo, uma vez que terminamos. Eu também não permite que nenhum dos threads de redirecionamento de saída ou erro se junte até que o processo tenha passado a chamada WaitForExit.
Estou completamente perplexo.
Peter, meu objetivo é:
Se você não chamar Dispose em um objeto que implemente (diretamente ou indiretamente) IDisposable, então você está apenas pedindo um bug. No entanto, não quero argumentar sobre isso sem parar. Você pode continuar a fazê-lo da maneira que você faz, e eu vou ficar com o meu. Enquanto não tivermos que manter o código de cada um, tudo bem.
Eu não concordo. Não é um "erro" para não chamar Dispose. Seus recursos não serão liberados imediatamente, mas o GC os liberará se precisar da memória (assumindo que o padrão Dispose está corretamente implementado e existe um finalizador). Se a classe que você está usando implementa um & quot; Close & quot; método que não faz todas as mesmas coisas como "Dispose & quot ;, Close deve ser documentado como tal ou há um bug na classe. Eu nunca encontrei uma classe de estrutura que implemente IDisposable e um método Close () que introduzisse um "quilo" quando Close foi chamado sem chamar Dispose. O padrão esmagador para Dispose / Close é que Dispose calls Close, bem como a configuração de um & quot; disposto & quot; flag (usado para jogar ObjectDisposedException).
Na verdade, isso é detalhado na Referência Geral do Framework: & quot; Ocasionalmente, um nome específico do domínio é mais apropriado do que Dispose. Por exemplo, um encapsulamento de arquivo pode querer usar o nome do método Fechar. Nesse caso, implemente Dispose em particular e crie um método Close público que chame Dispose. O exemplo de código a seguir ilustra esse padrão. Você pode substituir Fechar com um nome de método apropriado para seu domínio. & Quot; de Implementar finalizar e descartar para limpar recursos não gerenciados.
Bem como "Para certas classes de objetos, como arquivos ou objetos de conexão de banco de dados, um método Close melhor representa a operação lógica que deve ser executada quando o consumidor do objeto é concluído com o objeto. & Quot; de Melhorar o desempenho do código gerenciado (embora também também detalhe "Em casos bem escritos, ambos são funcionalmente equivalentes". Implica que usar Fechar é mais claro com "melhor representa".)
E, a propósito, um "uso" de & quot; O bloco também não o protege. Nada impede que você declare a variável fora do bloco (se eu me lembro corretamente), então ainda pode estar no escopo após o fim do bloco. Você precisa ser diligente ao escrever o código correto. Se você declara isso no & quot; usando & quot; declaração, é uma maneira. Mas descartar o uso da abordagem try / finally apenas porque deixa a variável no escopo não é realmente o ponto. Ainda precisa ser Dispose () 'D em algum lugar.
Mais uma vez, NÃO É uma Exceção que está sendo jogada, então não vejo detalhes de exceção. Eu não vou diretamente para o bloco catch no meu código, eu retomo DIRECTAMENTE após a chamada WaitForExit (). A janela que recebo é a mesma que você obtém quando CADA produto da Microsoft fecha inesperadamente e MS quer informações sobre o Crash. Então, novamente, não há detalhes de exceção. No entanto, em um dos logs do sistema, estou recebendo uma mensagem (traduzido do japonês)
"Erros de aplicação Devenv. exe ocorrem, 8.0.50727.762 versão dos erros ocorridos módulo msvcr80.dll, versão 8.0.50727.762, erro ocorreu endereço 0x00039001.
Para obter mais informações, go. microsoft/fwlink/events. asp o Helo e o Centro de suporte, por favor consulte. & Quot;
Eu assumi que seu aplicativo estava gerando a mensagem (nesse caso, você sempre deve obter uma exceção e um rastreamento de pilha); não ficou claro que você retomasse depois da chamada para WaitForExit (). Parece-me que a aplicação que você está executando está terminando anormalmente. Você está executando devenv. exe? Não tenho certeza do que você pode fazer no seu aplicativo para impedir que outro aplicativo termine de forma anormal.
Estou redirecionando a entrada padrão para passar nos diferentes comandos, porque eu estava tendo problemas para fazê-los funcionar como queria formar o StartInfo. Estou redirecionando os fluxos de Saída e Erro para verificar o que eles têm neles depois que o processo foi encerrado. Isso me permitirá verificar qualquer coisa que eu gostaria em qualquer fluxo, uma vez que terminamos. Eu também não permite que nenhum dos threads de redirecionamento de saída ou erro se junte até que o processo tenha passado a chamada WaitForExit.
Estou completamente perplexo.
Daí o motivo pelo qual eu continue afirmando que não era uma exceção e que meu código ainda funcionava o resto do caminho até a conclusão, conforme esperado.
Assim. Existe alguma maneira de capturar uma exceção de aplicativo dentro de um processo em execução se ainda não foi encerrado. Isso será a verdadeira questão.
Bem, eu tentei usar FindWindow e FindWindowEx junto com SendMessage, mas não consegui encontrar o identificador de janela correto. Mas, como eu sei que uma caixa de Msssage de relatórios de erros do Windows aparecerá, verifiquei se era seu próprio processo (e é). O processo é dwwin. exe (Dr. Watson Win) e tudo o que eu tinha que fazer era isso para me permitir corrigir o problema atual. Substitua o atual bloco de código abaixo para a declaração WaitForExit () que eu tinha anteriormente.
Proc. WaitForExit (60000); // um minuto.
Processo [] ProcArray = Process. GetProcessesByName (& quot; dildin & quot;);
foreach (Process ProcessFound em ProcArray)
Eu também verifiquei se você conseguiu obter o Process. MainWindowTitle (), mas está definido como & quot; & quot ;. Então, isso é um hack e eu realmente não gosto de usá-lo, mas funciona para a execução atual.
A Microsoft está conduzindo 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.
Waitforexit c #
A sobrecarga WaitForExit () () () é usada para fazer o thread atual aguardar até o processo associado terminar. Esse 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.
Esta sobrecarga garante que todo o processamento foi 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 foi redirecionada para manipuladores de eventos assíncronos.
Isso é, naturalmente, para. O que faz você pensar que não aguarda que o processo de nota termine? Quais são os sinais disso? Qual é a prova?
Processo p = novo Processo ();
MessageBox. Show (& quot; agora o navegador deve estar fechado & quot;);
Exceto que você não obtém um objeto de processo que você pode usar. Se você tentar.
Dim myProc como novo processo ()
myProc = Process. Start (& quot; iexplore & quot ;, & quot; finance. yahoo/q/hp? s = & quot; + symbol);
A Microsoft está conduzindo 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.
Processo . Método WaitForExit.
A documentação de referência da API tem uma nova casa. Visite o navegador da API no docs. microsoft para ver a nova experiência.
Define o período de tempo para aguardar o processo associado para sair e bloqueia o segmento de execução atual até o tempo decorrido ou o processo foi encerrado. Para evitar o bloqueio do segmento atual, use o evento Exitado.
Para exemplos de código, consulte as páginas de referência da propriedade StandardError e ExitCode.
Assembly: System (no System. dll)
Instrui o componente Processo a esperar indefinidamente para que o processo associado saia.
Instrui o componente Processo a aguardar o número especificado de milissegundos para que o processo associado saia.
Esta pergunta pode parecer um pouco estranha, mas estou tentando executar VS2005 através de um processo e executar um comando específico e eu waitforexit (). Estou redirecionando minha entrada e saída com sucesso, mas de vez em quando eu recebo uma Window Window / Message Window Window. O problema é que eu estou remoting, então quando esta mensagem / janela ocorre durante a execução do processo, eu vou pendurar a menos que eu logar na outra máquina (remota) e fechar a janela.
Existe alguma maneira de matar programaticamente esta janela ou possivelmente desativar a mensagem / janela? Eu pensei em executar o VS em uma execução silenciosa (ainda tenho que encontrar uma maneira de fazê-lo). Eu também tentei ver se há algo que está sendo lançado quando isso ocorre comparado ao quando não.
Bem, eu tentei usar FindWindow e FindWindowEx junto com SendMessage, mas não consegui encontrar o identificador de janela correto. Mas, como eu sei que uma caixa de Msssage de relatórios de erros do Windows aparecerá, verifiquei se era seu próprio processo (e é). O processo é dwwin. exe (Dr. Watson Win) e tudo o que eu tinha que fazer era isso para me permitir corrigir o problema atual. Substitua o atual bloco de código abaixo para a declaração WaitForExit () que eu tinha anteriormente.
Proc. WaitForExit (60000); // um minuto.
Processo [] ProcArray = Process. GetProcessesByName (& quot; dildin & quot;);
foreach (Process ProcessFound em ProcArray)
Eu também verifiquei se você conseguiu obter o Process. MainWindowTitle (), mas está definido como & quot; & quot ;. Então, isso é um hack e eu realmente não gosto de usá-lo, mas funciona para a execução atual.
Todas as respostas.
Você pode ser específico com o erro que está recebendo?
Isso ocorre apenas quando você está redirecionando a entrada e a saída?
Você está executando console? Cmd & quot; ?
Se sim, você deve digitar exit também.
// Processo interrompido antes do período de tempo limite.
// Imprimir mensagem de erro?
Gostaria de tentar isso, mas é muito um hack. Eu tenho muitos comandos diferentes que levam diferentes períodos de tempo (30 segundos a 25 minutos), então não há configurações de tempo real que eu poderia colocar sem destruir o meu desempenho. Esta função tem funcionado corretamente para vários comandos nos últimos 6 meses e agora ele decide sair para mim. Eu tentei em um computador diferente sem problemas (o que realmente está me mexendo). Eu sei que não é o redirecionamento de saída / erro porque uma nova WINDOW está sendo criada no servidor ao qual eu estou remoting. Assim que eu fechar essa janela, meu processo sai como esperado e a saída correta é exibida no lado do Usuário.
Obrigado pela sua ajuda, mas estou realmente frustrado com este problema.
Sem saber o detalhe da mensagem, estamos apenas adivinhando o problema.
Você instalou o beta 3.5 beta ou o Visual Studio 2008 beta?
Como você está usando o Processo para iniciar o programa, Process. Start (& quot; file. exe & quot;), ou você está usando ProcessStartInfo?
Não, eu tenho 2003 e 2005 instalados.
proc = new Process ();
procSI = novo ProcessStartInfo ();
Em seguida, configurei um novo tópico para o StandardError e StandardOutput.
Depois escrevo meus comandos e.
se (redirecionando o padrão para fora)
Inicie o tópico para o st. Fora.
Se (redirecionando o erro padrão)
Inicie o tópico para o st. erro.
Proc. WaitForExit (); & lt; -------- é onde ocorre a janela Generic Windows Reporting de Erros.
Eu traduzi o que pude da Janela que aparece.
問題 が 発 生 し た た め, Microsoft Visual Studio 2005 を 終了 し ま す. ご 不便 を お か け し て 申 し 訳 あ り ま せ ん.
Porque o problema ocorre, ele termina o Microsoft Visual Studio 2005. Aplicando inconvenientes, não há desculpa.
Obrigado novamente por todo o seu tempo.
Por que você está fazendo isso? Você não possui esse fluxo, então você não deve fechá-lo.
Isso é um erro de digitação? Antes de você falar sobre uma variável chamada "proc", não "Proc". Então, isso é simplesmente uma referência nula porque você está tentando invocar um método em uma referência diferente de "proc"?
Você não deseja fechar o objeto sIn até que o aplicativo tenha saído se você estiver redirecionando. Se o aplicativo grava a saída padrão ou lê da entrada padrão depois de fechar qualquer um desses, isso pode causar uma exceção.
Você tem o rastreamento da pilha dessa mensagem de erro?
Você não deseja fechar o objeto sIn até que o aplicativo tenha saído se você estiver redirecionando.
Não se deve fechar nenhum desses fluxos. O objeto Processo os possui e é o responsável pela limpeza depois de si próprio. Deveria, na melhor das hipóteses, chamar Process. Dispose () depois de terminar o objeto Processo.
Eu criei o SQL Server do StreamWriter antes de criar o objeto Proc Process. Eu então redireciono a entrada após o comando proc. Start (), então, como eu não possuo isso? Independentemente disso, posso fazer a mudança para mover o sIn. Close () para depois da chamada WaitForExit para ver se isso faz alterações.
O Proc era um tipo, deveria ter sido proc.
Novamente, não é uma mensagem de erro, portanto, não há rastreamento de pilha. O redirecionamento do meu StandardError está vazio eo redirecionamento de saída padrão contém o que eu esperava, mas nada indicando que ocorreu um erro. É por isso que tudo ainda funciona depois que eu fechar a janela de Relatório de Erros do Windows.
Posso publicar o que acontece depois de mover a linha sIn. Close () abaixo da linha WaitForExit ().
Você não deseja fechar o objeto sIn até que o aplicativo tenha saído se você estiver redirecionando.
Não se deve fechar nenhum desses fluxos. O objeto Processo os possui e é o responsável pela limpeza depois de si próprio. Deveria, na melhor das hipóteses, chamar Process. Dispose () depois de terminar o objeto Processo.
Ok, estou fazendo Process. Fechar no último bloco do meu código, então deve ser cuidada então.
Perceba o meu comentário "não próprio" que eu fiz anteriormente. Acabei de voltar de almoço e faltava o fato de que o processo tem controle disso.
Process. Close é o método recomendado para fechar os fluxos de entrada padrão e padrão (e padrão).
Eu ficaria surpreso se o método Dispose não chamasse de Fechar, pelo menos como parte de sua operação. Eu preferiria usar o fato de que, desde que o Processo implementa IDisposable (indiretamente através do componente de extensão que o implementa), um deve invocar Dispose e permitir que a limpeza adequada. Eu não recomendaria invocar Process. Close em vez de, nem além de, Process. Dispose.
Process. Close é o método recomendado para fechar os fluxos de entrada padrão e padrão (e padrão).
Eu ficaria surpreso se o método Dispose não chamasse de Fechar, pelo menos como parte de sua operação. Eu preferiria usar o fato de que, desde que o Processo implementa IDisposable (indiretamente através do componente de extensão que o implementa), um deve invocar Dispose e permitir que a limpeza adequada. Eu não recomendaria invocar Process. Close em vez de, nem além de, Process. Dispose.
Como tenho certeza que você sabe, estes são funcionalmente equivalentes:
usando (SomethingDisposable myObject =.)
// use myObject aqui.
// use myObject aqui.
se (myObject! = null) myObject. Dispose ();
Então, se a primeira recomendação for usar um bloco de uso, então o próximo melhor seria chamar Dispose, não Fechar, quando, como você disse, você sabe que você terminou com o objeto.
Ao ligar apenas perto de algo que implementa IDisposable, o desenvolvedor está cometer um erro. Se Dispose fizer alguma limpeza adicional além de apenas delegar para Fechar, então o programador está configurando-se para um bug, apenas ligando para Fechar.
Pode haver um caso para chamar Close, mas somente se você não tiver terminado com o objeto, como você indicou na parte inferior da sua última resposta. Mas quando terminar com isso, chame Dispose.
Como tenho certeza que você sabe, estes são funcionalmente equivalentes:
usando (SomethingDisposable myObject =.)
// use myObject aqui.
// use myObject aqui.
se (myObject! = null) myObject. Dispose ();
Então, se a primeira recomendação for usar um bloco de uso, então o próximo melhor seria chamar Dispose, não Fechar, quando, como você disse, você sabe que você terminou com o objeto.
Ao ligar apenas perto de algo que implementa IDisposable, o desenvolvedor está cometer um erro. Se Dispose fizer alguma limpeza adicional além de apenas delegar para Fechar, então o programador está configurando-se para um bug, apenas ligando para Fechar.
Pode haver um caso para chamar Close, mas somente se você não tiver terminado com o objeto, como você indicou na parte inferior da sua última resposta. Mas quando terminar com isso, chame Dispose.
DisposableClass obj = new DisposableClass ();
IDisposable descartable = obj como IDisposable;
se (descartável! = nulo)
Mas sim, é isso que uma declaração de uso é "equivalente funcionalmente" para; mas eu não concordo chamando explicitamente Dispose na presença de um & quot; Close & quot; O método deve ser a primeira escolha devido à falta de escopo com a chamada Dispose. Por exemplo, o seguinte:
usando (processo processo = novo processo ()
. é um erro de sintaxe.
Enquanto o seguinte:
Processo process = new Process ();
// não há como garantir o "processo" não vai.
// seja acessado após o acima.
É um erro em tempo de execução (ObjectDisposedException). Usar fechar não causa o erro de tempo de execução:
Processo process = new Process ();
É sempre melhor trocar um erro de tempo de compilação por um erro de tempo de execução.
Então, estabeleci um ponto de interrupção após a chamada proc. WaitForExit () e ainda não atingi este ponto de interrupção. Então parece que é um problema.
Então, estabeleci um ponto de interrupção após a chamada proc. WaitForExit () e ainda não atingi este ponto de interrupção. Então parece que é um problema.
Eu tinha o serviço funcionando, mas eu parei porque tinha funcionado por 2 horas e nunca tinha o ponto de interrupção que deveria ter atingido dentro de 10 minutos de mim, começando meu cliente. Eu não comentei a linha sIn. Close () agora e voltei a iniciar o serviço e o Cliente e tudo está funcionando como antes. Posso acertar o ponto de interrupção após o WaitForExit () e eu concluir, com a mensagem de relatório de erros do Windows ainda (como era antes).
Então, no meu caso, PRECISO fechar o fluxo de entrada para poder sair do processo conforme o esperado. Existem outras idéias?
Eu posso recomendar a linha sIn. Close () se você quiser verificar algo.
Eu tinha o serviço funcionando, mas eu parei porque tinha funcionado por 2 horas e nunca tinha o ponto de interrupção que deveria ter atingido dentro de 10 minutos de mim, começando meu cliente. Eu não comentei a linha sIn. Close () agora e voltei a iniciar o serviço e o Cliente e tudo está funcionando como antes. Posso acertar o ponto de interrupção após o WaitForExit () e eu concluir, com a mensagem de relatório de erros do Windows ainda (como era antes).
Então, no meu caso, PRECISO fechar o fluxo de entrada para poder sair do processo conforme o esperado. Existem outras idéias?
Eu posso recomendar a linha sIn. Close () se você quiser verificar algo.
Como você está usando a entrada padrão e a saída padrão? Você está usando algum método ReadLine?
Peter, meu objetivo é:
Se você não chamar Dispose em um objeto que implemente (diretamente ou indiretamente) IDisposable, então você está apenas pedindo um bug. No entanto, não quero argumentar sobre isso sem parar. Você pode continuar a fazê-lo da maneira que você faz, e eu vou ficar com o meu. Enquanto não tivermos que manter o código de cada um, tudo bem.
E, a propósito, um "uso" de & quot; O bloco também não o protege. Nada impede que você declare a variável fora do bloco (se eu me lembro corretamente), então ainda pode estar no escopo após o fim do bloco. Você precisa ser diligente ao escrever o código correto. Se você declara isso no & quot; usando & quot; declaração, é uma maneira. Mas descartar o uso da abordagem try / finally apenas porque deixa a variável no escopo não é realmente o ponto. Ainda precisa ser Dispose () 'D em algum lugar.
Eu tinha o serviço funcionando, mas eu parei porque tinha funcionado por 2 horas e nunca tinha o ponto de interrupção que deveria ter atingido dentro de 10 minutos de mim, começando meu cliente. Eu não comentei a linha sIn. Close () agora e voltei a iniciar o serviço e o Cliente e tudo está funcionando como antes. Posso acertar o ponto de interrupção após o WaitForExit () e eu concluir, com a mensagem de relatório de erros do Windows ainda (como era antes).
Então, no meu caso, PRECISO fechar o fluxo de entrada para poder sair do processo conforme o esperado. Existem outras idéias?
Eu posso recomendar a linha sIn. Close () se você quiser verificar algo.
Como você está usando a entrada padrão e a saída padrão? Você está usando algum método ReadLine?
Mais uma vez, NÃO É uma Exceção que está sendo jogada, então não vejo detalhes de exceção. Eu não vou diretamente para o bloco catch no meu código, eu retomo DIRECTAMENTE após a chamada WaitForExit (). A janela que recebo é a mesma que você obtém quando CADA produto da Microsoft fecha inesperadamente e MS quer informações sobre o Crash. Então, novamente, não há detalhes de exceção. No entanto, em um dos logs do sistema, estou recebendo uma mensagem (traduzido do japonês)
"Erros de aplicação Devenv. exe ocorrem, 8.0.50727.762 versão dos erros ocorridos módulo msvcr80.dll, versão 8.0.50727.762, erro ocorreu endereço 0x00039001.
Para obter mais informações, go. microsoft/fwlink/events. asp o Helo e o Centro de suporte, por favor consulte. & Quot;
Estou redirecionando a entrada padrão para passar nos diferentes comandos, porque eu estava tendo problemas para fazê-los funcionar como queria formar o StartInfo. Estou redirecionando os fluxos de Saída e Erro para verificar o que eles têm neles depois que o processo foi encerrado. Isso me permitirá verificar qualquer coisa que eu gostaria em qualquer fluxo, uma vez que terminamos. Eu também não permite que nenhum dos threads de redirecionamento de saída ou erro se junte até que o processo tenha passado a chamada WaitForExit.
Estou completamente perplexo.
Peter, meu objetivo é:
Se você não chamar Dispose em um objeto que implemente (diretamente ou indiretamente) IDisposable, então você está apenas pedindo um bug. No entanto, não quero argumentar sobre isso sem parar. Você pode continuar a fazê-lo da maneira que você faz, e eu vou ficar com o meu. Enquanto não tivermos que manter o código de cada um, tudo bem.
Eu não concordo. Não é um "erro" para não chamar Dispose. Seus recursos não serão liberados imediatamente, mas o GC os liberará se precisar da memória (assumindo que o padrão Dispose está corretamente implementado e existe um finalizador). Se a classe que você está usando implementa um & quot; Close & quot; método que não faz todas as mesmas coisas como "Dispose & quot ;, Close deve ser documentado como tal ou há um bug na classe. Eu nunca encontrei uma classe de estrutura que implemente IDisposable e um método Close () que introduzisse um "quilo" quando Close foi chamado sem chamar Dispose. O padrão esmagador para Dispose / Close é que Dispose calls Close, bem como a configuração de um & quot; disposto & quot; flag (usado para jogar ObjectDisposedException).
Na verdade, isso é detalhado na Referência Geral do Framework: & quot; Ocasionalmente, um nome específico do domínio é mais apropriado do que Dispose. Por exemplo, um encapsulamento de arquivo pode querer usar o nome do método Fechar. Nesse caso, implemente Dispose em particular e crie um método Close público que chame Dispose. O exemplo de código a seguir ilustra esse padrão. Você pode substituir Fechar com um nome de método apropriado para seu domínio. & Quot; de Implementar finalizar e descartar para limpar recursos não gerenciados.
Bem como "Para certas classes de objetos, como arquivos ou objetos de conexão de banco de dados, um método Close melhor representa a operação lógica que deve ser executada quando o consumidor do objeto é concluído com o objeto. & Quot; de Melhorar o desempenho do código gerenciado (embora também também detalhe "Em casos bem escritos, ambos são funcionalmente equivalentes". Implica que usar Fechar é mais claro com "melhor representa".)
E, a propósito, um "uso" de & quot; O bloco também não o protege. Nada impede que você declare a variável fora do bloco (se eu me lembro corretamente), então ainda pode estar no escopo após o fim do bloco. Você precisa ser diligente ao escrever o código correto. Se você declara isso no & quot; usando & quot; declaração, é uma maneira. Mas descartar o uso da abordagem try / finally apenas porque deixa a variável no escopo não é realmente o ponto. Ainda precisa ser Dispose () 'D em algum lugar.
Mais uma vez, NÃO É uma Exceção que está sendo jogada, então não vejo detalhes de exceção. Eu não vou diretamente para o bloco catch no meu código, eu retomo DIRECTAMENTE após a chamada WaitForExit (). A janela que recebo é a mesma que você obtém quando CADA produto da Microsoft fecha inesperadamente e MS quer informações sobre o Crash. Então, novamente, não há detalhes de exceção. No entanto, em um dos logs do sistema, estou recebendo uma mensagem (traduzido do japonês)
"Erros de aplicação Devenv. exe ocorrem, 8.0.50727.762 versão dos erros ocorridos módulo msvcr80.dll, versão 8.0.50727.762, erro ocorreu endereço 0x00039001.
Para obter mais informações, go. microsoft/fwlink/events. asp o Helo e o Centro de suporte, por favor consulte. & Quot;
Eu assumi que seu aplicativo estava gerando a mensagem (nesse caso, você sempre deve obter uma exceção e um rastreamento de pilha); não ficou claro que você retomasse depois da chamada para WaitForExit (). Parece-me que a aplicação que você está executando está terminando anormalmente. Você está executando devenv. exe? Não tenho certeza do que você pode fazer no seu aplicativo para impedir que outro aplicativo termine de forma anormal.
Estou redirecionando a entrada padrão para passar nos diferentes comandos, porque eu estava tendo problemas para fazê-los funcionar como queria formar o StartInfo. Estou redirecionando os fluxos de Saída e Erro para verificar o que eles têm neles depois que o processo foi encerrado. Isso me permitirá verificar qualquer coisa que eu gostaria em qualquer fluxo, uma vez que terminamos. Eu também não permite que nenhum dos threads de redirecionamento de saída ou erro se junte até que o processo tenha passado a chamada WaitForExit.
Estou completamente perplexo.
Daí o motivo pelo qual eu continue afirmando que não era uma exceção e que meu código ainda funcionava o resto do caminho até a conclusão, conforme esperado.
Assim. Existe alguma maneira de capturar uma exceção de aplicativo dentro de um processo em execução se ainda não foi encerrado. Isso será a verdadeira questão.
Bem, eu tentei usar FindWindow e FindWindowEx junto com SendMessage, mas não consegui encontrar o identificador de janela correto. Mas, como eu sei que uma caixa de Msssage de relatórios de erros do Windows aparecerá, verifiquei se era seu próprio processo (e é). O processo é dwwin. exe (Dr. Watson Win) e tudo o que eu tinha que fazer era isso para me permitir corrigir o problema atual. Substitua o atual bloco de código abaixo para a declaração WaitForExit () que eu tinha anteriormente.
Proc. WaitForExit (60000); // um minuto.
Processo [] ProcArray = Process. GetProcessesByName (& quot; dildin & quot;);
foreach (Process ProcessFound em ProcArray)
Eu também verifiquei se você conseguiu obter o Process. MainWindowTitle (), mas está definido como & quot; & quot ;. Então, isso é um hack e eu realmente não gosto de usá-lo, mas funciona para a execução atual.
A Microsoft está conduzindo 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.
No comments:
Post a Comment