Tuesday 21 November 2017

C # Process Class Waitforexit


Sua solução não precisa de 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 Jan 13 15 at 10:35 Exemplo de uso Implementação Esta questão pode parecer um pouco estranho, mas eu 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 êxito, mas de vez em quando, por acaso, recebo uma Janela de Relatórios de Erros de Janela / Mensagem. O problema é que estou remoting, então quando essa mensagem / janela ocorre durante a execução do processo, eu vou pendurar a menos que eu log na outra máquina (remoting) e feche a janela. Existe alguma maneira de programaticamente matar esta janela ou possivelmente desativar a mensagem / janela de ocorrer Tenho pensado em executar VS em uma execução silenciosa (eu ainda tenho que encontrar uma maneira de fazê-lo). Eu também tentei ver se há alguma coisa sendo lançado quando isso ocorre comparar a quando não. Bem, eu tentei usar FindWindow e FindWindowEx junto com SendMessage, mas eu não conseguia encontrar o identificador de janela correto. Mas desde que eu sei que um erro do Windows Msssage Box Reporting será popping up, verifiquei para ver se ele 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. Substituir o bloco de código atual abaixo para a declaração WaitForExit () que eu tinha anteriormente. Proc. WaitForExit (60000) // um minuto Process ProcArray Process. GetProcessesByName (quotdwwinquot) foreach (Process ProcessFound no ProcArray) Eu também verifiquei se você foi capaz de obter o Process. MainWindowTitle (), mas é definido como quotquot. Então este é um hack e eu realmente não gosto de usá-lo, mas ele funciona para a execução atual. Segunda-feira, 29 de outubro de 2007 19:26 Não, eu posso redirecionar entrada e saída sem um problema. O erro que estou recebendo é o relatório geral de erro do Windows e, infelizmente, é em japonês, então eu não sei qual é o erro exato, mas é o erro geral. Eu não tenho o código na minha frente, mas eu configurar delegados / segmentos para ler redirecionado o erro e saída depois de sair todo o processo. Eu não posso vir acima com qualquer coisa e eu sou capaz de executar o mesmo processo no meu próprio computador, mas eu não sou capaz de fazer um determinado comando através de remoting. Vou experimentá-lo amanhã remoting em uma máquina não-japonesa no trabalho e vou publicar minhas descobertas independentemente. Sexta-feira, 26 de outubro de 2007 2:34 Você está executando console quotcmdquot. Se sim, então você tem que digitar exit também. Se você tiver uma idéia de quanto tempo o seu processo vai demorar, então você pode usar bool exitted process. WaitForExit (timeInMilliSeconds) if (exitted) // Processa saída antes do tempo limite. Else // Imprimir mensagem de erro Isto pode não estar relacionado com o que você está fazendo, mas eu tive uma experiência onde o processo não iria sair se eu redirecionasse sua saída. Tente desabilitar o redirecionamento de saída e veja se o processo é encerrado. Experimente, pode funcionar. Sexta-feira, outubro 26, 2007 11:58 AM Eu gostaria de tentar isso, mas é muito de um hack. Eu tenho muitos comandos diferentes que levam diferentes quantidades de tempo (30 segundos a 25 minutos) para que não haja configuração 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 em mim. Eu tentei em um computador diferente, sem problemas (que é realmente mexer comigo). Eu sei que não é o redirecionamento de saída / erro porque um novo WINDOW está sendo criado no servidor que estou remoting para. Assim que 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 ficando realmente frustrado com este problema. Sexta-feira, 26 de outubro de 2007 15:01 Sem saber o detalhe da mensagem estavam apenas adivinhando o problema. Você já instalou beta do. NET 3.5 ou beta do Visual Studio 2008 em todos os Como você está usando o processo para iniciar o programa, Process. Start (quotfile. exequot), ou você está usando ProcessStartInfo sexta-feira, 26 de outubro de 2007 15:21 Não, Eu tenho o. NET 2003 eo. NET 2005 instalado. Proc new Process () procSI new ProcessStartInfo () Eu, em seguida, configurar um novo segmento para o StandardError e StandardOutput Eu, em seguida, escrever meus comandos e se (redirecionamento padrão) Start thread para st. Out Se (redirecionando erro padrão) Inicie thread para st. Erro Proc. WaitForExit () lt -------- este é o local onde a janela Generic Windows Error Reporting ocorre. Eu traduzi o que eu poderia da janela que aparece. Microsoft Visual Studio 2005 Porque problema ocorre, ele termina Microsoft Visual Studio 2005. Estamos aplicando inconveniência, não há desculpa. Obrigado novamente por todo o seu tempo. Criei o StreamWriter sIn antes de criar o objeto proc Process. Eu, em seguida, redirecionar a entrada após o comando proc. Start (), então como eu não possui este Independentemente, eu posso fazer a alteração para mover o sIn. Close () para após a chamada WaitForExit para ver se isso faz quaisquer alterações. O Proc era um tipo, deveria ter sido proc. Novamente, não é uma mensagem de erro, portanto, não há nenhum rastreamento de pilha. Meu redirecionamento StandardError está vazio eo redirecionamento Standard OUtput contém o que eu esperava, mas nada indicando um erro ocorreu. É por isso que tudo ainda funciona depois de fechar a janela Relatório de erros do Windows. Vou publicar o que acontece depois de mover a linha sIn. Close () abaixo da linha WaitForExit (). Sexta-feira, 26 de outubro de 2007 16:59 Peter Ritchie escreveu: Você não quer fechar o objeto sIn até depois que a aplicação tenha saído se você está redirecionando. Não se deve fechar nenhum desses fluxos. O objeto Processo os possui e é o responsável pela limpeza depois de si. Um deve no melhor chamar Process. Dispose () depois de terminar com o objeto Process. Você certamente não precisa (ou seja, o seu redundante), mas não deve causar um problema após o processo saiu. Process. Close é o método recomendado para fechar os fluxos standardinput e standardoutput (e standarderror). Sexta-feira, outubro 26, 2007 5:03 PM Eu seria surpised se o método de Dispose didnt chamar Close, pelo menos como parte de sua operação. Gostaria de usar o fato de que, uma vez que o processo implementa IDisposable (indiretamente através de estender Componente que implementa), deve-se invocar Dispose e deixar que a limpeza adequada. Eu wouldnt recomendam invocando Process. Close em vez de, nem além disso, Process. Dispose. Sim, descartar chamadas Fechar. Minha primeira recomendação é usar um bloco usando, o segundo é chamar Close quando você sabe quando você está feito com ele. Em objetos que implementam um método quotClosequot apesar de ser IDisposable, é muito mais claro usar o método quotClosequot. Além disso, sem utilizar um bloco de uso você não tem nenhuma maneira de escopo a variável ea chamada para Dispose - o objeto poderia ser usado após a chamada para Dispose. Se você usar o Close youve, descartou todos os recursos gerenciados, mas o objeto ainda pode ser usado (isto é, ele não foi sinalizado como quotdisposedquot e você pode usá-lo para executar outro aplicativo sem alocar um novo objeto Process - que de outra forma lançaria um ObjectDisposedException ). Sexta-feira, 26 de outubro de 2007 18:09 Então, se a primeira recomendação é usar um bloco usando, então o próximo melhor seria chamar Dispose. Não Close, quando, como você disse, você sabe que está feito com o objeto. Ao chamar Close em algo que implementa IDisposable, o desenvolvedor está potencialmente cometendo um erro. Se o Dispose fizer alguma limpeza adicional além de apenas delegar para Fechar, o programador está configurando-se para um bug por apenas chamar Fechar. Pode haver um caso para chamar Close, mas somente se você não tiver feito com o objeto, como você indicou na parte inferior da sua última resposta. Mas quando terminar, chame Dispose. Então, se a primeira recomendação é usar um bloco usando, então o próximo melhor seria chamar Dispose. Não Close, quando, como você disse, você sabe que está feito com o objeto. Ao chamar Close em algo que implementa IDisposable, o desenvolvedor está potencialmente cometendo um erro. Se o Dispose fizer alguma limpeza adicional além de apenas delegar para Fechar, o programador está configurando-se para um bug por apenas chamar Fechar. Pode haver um caso para chamar Close, mas somente se você não tiver feito com o objeto, como você indicou na parte inferior da sua última resposta. Mas quando terminar, chame Dispose. Na verdade, seu quotmorequot equivalente a: DisposableClass obj new DisposableClass () IDisposable descartável obj como IDisposable if (null descartável) Mas sim, isso é o que uma instrução using é quotfunctionally equivalente a mas eu não concordo explicitamente chamando Dispose na presença de um método quotClosequot deve Ser a primeira escolha devido à falta de escopo com a chamada Dispose. Por exemplo, o seguinte: using (Process process new Process ()) Eu tinha o serviço em execução, mas eu parei porque ele tinha corrido por 2 horas e nunca tinha o ponto de interrupção que deveria ter acertado dentro de 10 minutos de começar meu cliente. Eu descomentado a linha sIn. Close () apenas agora e re-iniciado o serviço eo cliente e tudo está funcionando como ele fez antes. Eu posso acertar o ponto de interrupção após o WaitForExit () e eu completo, com a mensagem de relatório de erro do Windows ainda (como era antes). Então, no meu caso, eu preciso fechar o fluxo de entrada para poder sair do processo como esperado. Existem outras idéias que eu possa recomment a linha sIn. Close () se você gostaria de verificar algo. Sexta-feira, 26 de outubro de 2007 19:19 Anthony Maimone escreveu: Eu tinha o serviço em execução, mas eu parei porque ele tinha corrido por 2 horas e nunca tinha o ponto de interrupção que deveria ter acertado dentro de 10 minutos de começar meu cliente . Eu descomentado a linha sIn. Close () apenas agora e re-iniciado o serviço eo cliente e tudo está funcionando como ele fez antes. Eu posso acertar o ponto de interrupção após o WaitForExit () e eu completo, com a mensagem de relatório de erro do Windows ainda (como era antes). Então, no meu caso, eu preciso fechar o fluxo de entrada para poder sair do processo como esperado. Existem outras idéias que eu possa recomment a linha sIn. Close () se você gostaria de verificar algo. Seria útil ver os detalhes da exceção quando você recebe o erro (como a pilha de chamadas). Como você está usando a entrada padrão ea saída padrão Você está usando qualquer método ReadLine Peter, meu ponto é: Se você não chamar Dispose em um objeto que implementa (direta ou indiretamente) IDisposable, então você está apenas pedindo um bug. Eu não quero discutir sobre isso interminável embora. Você pode continuar a fazê-lo da maneira que você faz, e eu vou ficar com o meu. Contanto que nós não temos que manter cada outro código, fino. E, a propósito, um quotusingquot bloco não protege você também. Nada impede que você declare a variável fora do bloco (se bem me lembro), então ainda pode estar no escopo depois que o bloco termina. Você tem que ser diligente em escrever o código correto. Se você declará-lo na declaração quotusingquot, thats uma maneira. Mas descartar usando a abordagem try / finally apenas porque deixa a variável no escopo não é realmente o ponto. Ele ainda precisa ser Dispose () d em algum lugar. Anthony Maimone escreveu: Eu tinha o serviço em execução, mas eu parei porque ele tinha corrido por 2 horas e nunca tinha o ponto de interrupção que deveria ter atingido dentro de 10 minutos de Eu começando meu cliente. Eu descomentado a linha sIn. Close () apenas agora e re-iniciado o serviço eo cliente e tudo está funcionando como ele fez antes. Eu posso acertar o ponto de interrupção após o WaitForExit () e eu completo, com a mensagem de relatório de erro do Windows ainda (como era antes). Então, no meu caso, eu preciso fechar o fluxo de entrada para poder sair do processo como esperado. Existem outras idéias que eu possa recomment a linha sIn. Close () se você gostaria de verificar algo. Seria útil ver os detalhes da exceção quando você recebe o erro (como a pilha de chamadas). Como você está usando a entrada padrão ea saída padrão Você está usando qualquer método ReadLine Mais uma vez, esta não é uma exceção que está sendo lançada, então eu não estou vendo detalhes de exceção. Eu não vou diretamente para o bloco catch no meu código, eu retomar DIRETAMENTE após a chamada WaitForExit (). A janela que estou recebendo é a mesma que você recebe quando qualquer 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 quotDevenv. exe ocorrem, 8.0.50727.762 versão dos erros ocorreu msvcr80.dll módulo, versão 8.0.50727.762, erros ocorreram endereço 0x00039001. Para obter mais informações, go. microsoft/fwlink/events. asp o Helo e Centro de Suporte por favor refer. quot Estou redirecionando a entrada padrão para passar nos diferentes comandos em porque eu estava tendo problemas para fazê-los trabalhar como eu queria formar o StartInfo . Estou redirecionando os fluxos de saída e erro para verificar o que eles têm neles após o processo ter saído. Isto permitirá que eu verifique para qualquer coisa que eu gostaria em um ou outro córrego uma vez que nós terminamos. Eu também não permitem qualquer um dos segmentos de saída ou de redirecionamento de erro para participar até que após o processo passou a chamada WaitForExit. Estou completamente perplexo. Peter, o meu ponto é: Se você não chamar Dispose em um objeto que implementa (direta ou indiretamente) IDisposable, então você está apenas pedindo um bug. Eu não quero discutir sobre isso interminável embora. Você pode continuar a fazê-lo da maneira que você faz, e eu vou ficar com o meu. Contanto que nós não temos que manter cada outro código, fino. Eu não concordo. Não é um quotbugquot para não chamar Dispose. Seus recursos não serão liberados imediatamente, mas o GC irá liberá-los se precisar da memória (assumindo que o padrão Dispose é implementado corretamente e existe um finalizador). Se a classe que você está usando implementa um método quotClosequot que não faz todas as mesmas coisas que quotDisposequot, Close deve ser documentado como tal ou theres um bug na classe. Ive nunca encontrou uma classe de estrutura que implementa IDisposable e um método Close () que introduziu um quotleakquot quando Close foi chamado sem chamar Dispose. O esmagador padrão para Dispose / Close é que Dispose chama Close, bem como definir um quotdisposedquot sinalizador (usado para lançar ObjectDisposedException). Na verdade, isso é detalhado na referência geral do. NET Framework: quotOccasionally 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 Close. Nesse caso, implemente Dispose privadamente e crie um método Close público que chama Dispose. O exemplo de código a seguir ilustra esse padrão. Você pode substituir o Close por um nome de método apropriado para o seu domain. quot de Implementando Finalize e Dispose para Limpar Recursos Não Gerenciados Assim como quotFor certas classes de objetos, como arquivos ou objetos de conexão de banco de dados, um método Close representa melhor a operação lógica que Deve ser executado quando o consumidor de objetos é terminado com o objeto. quot de Improving Managed Code Performance (embora também ele também detalha quotIn casos bem escritos, ambos são funcionalmente equivalentes. quot implica que usando Close é mais claro com quotbetter representaquot.) E, a propósito, um quotusingquot bloco não protege você também. Nada impede que você declare a variável fora do bloco (se bem me lembro), então ainda pode estar no escopo depois que o bloco termina. Você tem que ser diligente em escrever o código correto. Se você declará-lo na declaração quotusingquot, thats uma maneira. Mas descartar usando a abordagem try / finally apenas porque deixa a variável no escopo não é realmente o ponto. Ele ainda precisa ser Dispose () d em algum lugar. Sim, há todos os tipos de maneiras que você pode atirar-se no pé, mas isso não é um cenário que estávamos discutindo. Eu pessoalmente derrubar qualquer código que eu revista como esse. Isso seria na minha lista não recomendada. Sexta-feira, 26 de outubro de 2007 7:54 Mais uma vez, isso não é uma exceção que está sendo lançada, portanto, não estou vendo detalhes de exceção. Eu não vou diretamente para o bloco catch no meu código, eu retomar DIRETAMENTE após a chamada WaitForExit (). A janela que estou recebendo é a mesma que você recebe quando qualquer 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 quotDevenv. exe ocorrem, 8.0.50727.762 versão dos erros ocorreu msvcr80.dll módulo, versão 8.0.50727.762, erros ocorreram endereço 0x00039001. Para mais informações, go. microsoft/fwlink/events. asp o Helo e Centro de Suporte por favor refer. quot Eu assumi que seu aplicativo estava gerando a mensagem (caso em que você deve sempre obter uma exceção e um rastreamento de pilha) não era claro que você Retomar após a chamada para WaitForExit (). Parece-me que o aplicativo que você está executando está terminando anormalmente. Você está executando devenv. exe Não tenho certeza o que você pode fazer em seu aplicativo para impedir que outro aplicativo de terminar anormalmente. Anthony Maimone escreveu: Estou redirecionando a entrada padrão para passar nos diferentes comandos em porque eu estava tendo problemas para fazê-los funcionar como eu queria formar o StartInfo. Estou redirecionando os fluxos de saída e erro para verificar o que eles têm neles após o processo ter saído. Isto permitirá que eu verifique para qualquer coisa que eu gostaria em um ou outro córrego uma vez que nós terminamos. Eu também não permitem qualquer um dos segmentos de saída ou de redirecionamento de erro para participar até que após o processo passou a chamada WaitForExit. Estou completamente perplexo. Você pode obter um impasse se você bloquear na leitura de e saída de aplicativos padrão - que iria desbloquear se você fechou o fluxo, acredito. A única coisa que eu posso pensar é criar um aplicativo que está sendo executado no servidor e monitorar janelas que vêm formam os processos que você está controlando remotamente e, em seguida, encontrar os botões corretos e pressioná-los programaticaly empurrando uma mensagem para a mensagem bomba da janela de diálogo . Este alos acontece com excel, palavra e outras aplicações que podem ser usadas com autimation MSFT não projetar esses aplicativos para ser executado sem interação do usuário de vez em quando você vai ter janelas sobre erros. Você já considerou usar MSBuid que é mais apropriado para compilações em lote, também parece que em TFS 2008 construir servidores será fácil de construir. Sábado, 27 de outubro de 2007 11:07 Bem, eu tentei usar FindWindow e FindWindowEx junto com SendMessage mas eu era incapaz de encontrar o identificador de janela correto. Mas desde que eu sei que um erro do Windows Msssage Box Reporting será popping up, verifiquei para ver 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. Substituir o bloco de código atual abaixo para a declaração WaitForExit () que eu tinha anteriormente. Proc. WaitForExit (60000) // um minuto Process ProcArray Process. GetProcessesByName (quotdwwinquot) foreach (Process ProcessFound no ProcArray) Eu também verifiquei se você foi capaz de obter o Process. MainWindowTitle (), mas é definido como quotquot. Então este é um hack e eu realmente não gosto de usá-lo, mas ele funciona para a execução atual. Segunda-feira, 29 de outubro de 2007 7:26 PMProcess. WaitForExit Method () WaitForExit () faz com que o thread atual aguarde até que o processo associado termine. Ele deve ser chamado depois que todos os outros métodos são chamados no processo. Para evitar bloquear o thread atual, use o evento Exited. Este método instrui o componente de processo para aguardar uma quantidade infinita de tempo para o processo e manipuladores de eventos para sair. Isso pode causar um aplicativo para parar 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 escrito para nunca inserir seu loop de mensagem. No. NET Framework 3.5 e versões anteriores, a sobrecarga WaitForExit () aguardou milissegundos MaxValue (aproximadamente 24 dias), não indefinidamente. Além disso, versões anteriores não aguardaram os manipuladores de eventos para sair se o tempo MaxValue total foi 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 (isto é, quando é desligado pelo sistema de operação através de uma terminação normal ou anormal), o sistema armazena informações administrativas sobre o processo e retorna ao componente que tinha chamado WaitForExit (). O componente de processo pode acessar as informações, que inclui o ExitTime. Usando o identificador para o processo de saída. Como o processo associado foi encerrado, a propriedade Handle do componente não aponta para um recurso de processo existente. Em vez disso, o identificador pode ser usado apenas para acessar os sistemas operacionais informações sobre o recurso de processo. O sistema está ciente de alças para processos encerrados que não foram liberados pelos componentes do processo, portanto, mantém as informações ExitTime e Handle na memória até que o componente Process libera especificamente os recursos. Por esse motivo, sempre que você chama Iniciar para uma instância Process, chame Close quando o processo associado tiver terminado e você não precisa mais nenhuma informação administrativa sobre ele. Fechar libera a memória alocada para o processo encerrado.

No comments:

Post a Comment