Como iniciar um processo e esperar para completar? #PowerShell.
Como iniciar um processo e esperar que ele seja concluído? #PowerShell.
Um dos novos Cmdlets apresentados com o PowerShell v2 é chamado Start-Process. Ele inicia um processo no computador local e, opcionalmente, aguarda a conclusão se você usar o parâmetro de Comutação Wait do Cmdlet. Start-Process é implementado usando o método Start da classe System. Diagnostics. Process do NET Framework.
A primeira versão do Windows PowerShell não veio com um cmdlet como Start-Process. A função abaixo, também chamada de Start-Process, aguarda a conclusão do processo por padrão. Além disso, a função aguardará que todos os processos filho do processo sejam concluídos se você usar o parâmetro de opção WaitForChildProcesses. Além disso, a função não esperará infinitamente, pois suporta um parâmetro Timeout. Por padrão, ele aguardará 600 segundos para que um processo (e processos filho) seja concluído. Como o Start-Process de Posh v2, a função usa a classe System. Diagnostics. Process NET Framework.
Então, por que esperar por processos filhos? Se é importante aguardar a conclusão do processo, talvez esperar que seus processos filhos também concluam os problemas. Por exemplo, o instalador do Oracle chama o Java e termina enquanto o Java Runtime ainda está ocupado instalando o software.
Além disso, considero um tempo limite como obrigatório para evitar uma espera infinita devido a um processo de suspensão (ou processo filho).
BTW, é claro que você pode usar a função no PowerShell v2 também. Lembre-se de que a função tem duas vantagens: aguardar processos filhos e tempo limite!
Processo . Método WaitForExit (Int32)
A documentação de referência da API tem uma nova casa. Visite o Navegador da API em docs. microsoft para ver a nova experiência.
Instrui o componente Processo a aguardar o número especificado de milissegundos para o processo associado sair.
Assembly: System (no System. dll)
Parâmetros
O período de tempo, em milissegundos, para aguardar a saída do processo associado. O máximo é o maior valor possível de um inteiro de 32 bits, que representa infinito para o sistema operacional.
Valor de retorno.
true se o processo associado tiver saído; Caso contrário, false.
A configuração de espera não pôde ser acessada.
Nenhuma identificação de processo foi definida e uma Handle da qual a propriedade Id pode ser determinada não existe.
Não há processo associado a este objeto Process.
Você está tentando chamar WaitForExit (Int32) para um processo que está sendo executado em um computador remoto. Este método está disponível apenas para processos em execução no computador local.
WaitForExit (Int32) faz com que o segmento atual espere até que o processo associado termine. Deve ser chamado depois que todos os outros métodos forem chamados no processo. Para evitar o bloqueio do segmento atual, use o evento Exited.
Este método instrui o componente Process a aguardar uma quantidade finita de tempo para o processo sair. Se o processo associado não sair no final do intervalo porque a solicitação para finalizar é negada, false é retornado para o procedimento de chamada. Você pode especificar um número negativo (Infinito) por milissegundos e Processo. WaitForExit (Int32) se comportará da mesma maneira que a sobrecarga WaitForExit (). Se você passar 0 (zero) para o método, ele retornará true somente se o processo já tiver saído; caso contrário, retorna imediatamente false.
No Framework 3.5 e em versões anteriores, se milissegundos fosse -1, a sobrecarga WaitForExit (Int32) aguardava milissegundos MaxValue (aproximadamente 24 dias), não indefinidamente.
Quando a saída padrão foi redirecionada para manipuladores de eventos assíncronos, é possível que o processamento de saída não seja concluído quando esse método retornar. Para garantir que o tratamento assíncrono de eventos tenha sido concluído, chame a sobrecarga WaitForExit () que não recebe nenhum parâmetro após receber um valor verdadeiro dessa sobrecarga. Para ajudar a garantir que o evento Exited seja tratado corretamente nos aplicativos do Windows Forms, defina a propriedade SynchronizingObject.
Quando um processo associado sai (é desligado pelo sistema operacional por meio de uma finalização normal ou anormal), o sistema armazena informações administrativas sobre o processo e retorna ao componente que chamou WaitForExit (Int32). 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 mais para um recurso de processo existente. Em vez disso, o identificador pode ser usado apenas para acessar as informações do sistema operacional sobre o recurso do processo. O sistema está ciente de identificadores para processos que não foram liberados pelos componentes do processo, portanto, ele mantém as informações de ExitTime e identificador na memória até que o componente de processo especificamente libera os recursos. Por esse motivo, sempre que você chamar a instância Start for Process, chame Close quando o processo associado tiver terminado e você não precisar mais de nenhuma informação administrativa sobre ele. Close libera a memória alocada para o processo finalizado.
Tempo limite padrão do Waitforexit
Eu tenho uma ferramenta que pode demorar muito tempo para executar, mais do que o tempo limite padrão do Powershell para iniciar o processo de 600 segundos. Então, estou tentando encontrar uma maneira de aumentar esse tempo limite. Se meu código de teste for executado assim sem um tempo limite especificado:
Em seguida, o script aguarda corretamente que o comando seja executado e saia:
PS U: \ Meus documentos \ Desenvolvimento \ PowerShell & gt; \ ping_test. ps1.
No entanto, se eu tentar adicionar um tempo limite ao comando:
O processo de ping ainda é iniciado, mas imediatamente retorna ao script do PowerShell e eu recebo esta saída:
o log de Walter.
. Escrevendo enquanto aprende.
Sexta-feira, 18 de novembro de 2011.
Process. WaitForExit (Int32) trava o problema.
Como você pode ver, o código inicia um processo "cmd. exe" e passa para ele o comando que eu quero executar.
No código eu usei o comando ping - t 8.8.8.8 que, por causa da opção - t, pinga o host sem parar. O que acontece? O processo "cmd. exe" juntamente com o comando ping - t nunca sai e nunca fecha o fluxo stdout e, portanto, o código trava no Output = process. StandardOutput. ReadToEnd (); linha porque não pode ter sucesso lendo 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.
Você pode experimentar um deadlock se o comando que você anexar a "cmd. exe" ou o processo que você está chamando preencher a saída padrão ou o erro padrão. Isso porque nosso código não pode alcançar as linhas.
Na verdade, o processo filho (o comando ping ou um arquivo em lote ou qualquer outro processo que você esteja executando) não pode continuar se nosso programa não ler os buffers preenchidos dos fluxos e isso não pode acontecer porque o código está pendurado na 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:
Tempo limite padrão do Waitforexit
Eu estou lutando contra um par estúpido de linhas de código com resultados muito estranhos. Estou executando o Win7.
O objetivo é iniciar um arquivo de comando (.cmd) a partir de um programa e esperar que este. cmd termine (com tempo limite).
Dentro do arquivo. cmd, há um comando TASKKILL. TASKKILL / F / T / IM CI. EXE.
Funciona perfeitamente ! Mas.
Se a tela de login é mostrada (o usuário está logado, mas a sessão está bloqueada), o TASKKILL está funcionando, mas o WaitForExit nunca termina, mesmo após o tempo limite.
Existe alguma boa explicação para isso e uma sugestão de solução alternativa? Desde já, obrigado !
Obrigado pelo seu tempo e sugestão.
No final, decidi reescrever meu próprio TASKKILL com um código C # muito simples, baseado em:
foreach (Process proc em Process. GetProcessByName ("CI")) (Ci é o nome do processo que eu quero matar)
E milagre! funciona ! Então, estou pensando que a TASKKILL faz muito mais do que apenas matar um processo.
Na verdade, meu bug agora está corrigido, então configurarei o thread como Respondido.
Obrigado pela sua leitura!
Marcado como Resposta dt51 sexta-feira, 8 de abril de 2016 14:42.
Todas as respostas.
Estou assumindo que o Tempo limite significa que você está definindo algum tempo para aguardar a saída do processo. Em caso afirmativo, tente deixar o processo para sair. Em vez de esperar algum período de tempo.
Para mais informações, leia este artigo: Método Process. WaitForExit ()
Editado por Sabah Shariq MVP, Moderador sexta-feira, 8 de abril de 2016 10:01.
Obrigado pelo seu tempo e resposta. Infelizmente, isso não funciona.
Eu estou com a idéia de que o TASKKILL vai causar alguma perturbação no método Process. WaitForExit. Na verdade, os dois estão trabalhando na mesma área.
Eu vou criar minha própria versão do TASKKILL de C #, mas não sou tão otimista. Te informaremos.
Se você tiver outra ideia, será bem-vindo!
Tem que ser principalmente acho que aqui. Além dos estados elevados / não elevados, há também o conceito de uma sessão interativa / não interativa.
Qual é o contexto exato em que o código está sendo executado?
Process. WaitForExit () tem este pequeno aviso:
& quot; Este método instrui o componente Process a aguardar uma quantidade infinita de tempo para que os manipuladores de processo e evento saiam. 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 encerrar o processo associado pode não ser tratada se o processo for gravado para nunca inserir seu loop de mensagem. & Quot;
Pode ser que enquanto a área de trabalho está bloqueada (o usuário não está logado corretamente), não há sessão interativa. Ou talvez nenhum dos loops de mensagens responda por padrão, pois processá-los custaria apenas recursos da CPU?
Ou talvez o contrário: não ter uma sessão interativa para começar pode permitir que o programa continue a ser executado. Esse código é executado em um serviço? Se não, que tal movê-lo para lá?
Tempo limite padrão do Waitforexit
se eu iniciar outro aplicativo CF usando o seguinte código no NetCF2.0, o aplicativo nunca sai, ele simplesmente parece travar?
Dim p como novo processo.
Dim info As New ProcessStartInfo (& quot; Sync. exe & quot ;, & quot; 1 & quot;)
Se eu executar o aplicativo manualmente ou percorrê-lo, ele sai conforme o esperado. É quase como se o WaitForExit estivesse vivo ou algo assim?
Se você tiver uma repro fi nição confiável que não esteja usando componentes de terceiros, preencha um relatório de bug aqui.
Todas as respostas.
Não, WaitForExit () apenas espera por aplicativo para saídas, ele não o mantém ativo. Deve ser algo no Sync. exe que nunca sai se for lançado pelo aplicativo principal. Pode ser que o Sync. exe espere pelo recurso mantido pelo aplicativo principal, cabe a você investigar.
Sim, eu acho que vou ter que fazer mais algumas escavações.
Eu escrevi um programa de exemplo com um formulário com um botão ligado, quando o botão foi clicado, disparou Sync. exe e chamou WaitForExit () e tudo funcionou bem! Confuso!!
Pode ter algo a ver com o fato de que o código que chama o Sync. exe está em um thread separado, talvez? Vou postar de volta quando encontrar a resposta!
Essa fila é usada para o IPC enviar mensagens básicas do Sync. exe para o aplicativo de chamada principal. Essas mensagens são strings básicas, geralmente um caractere "c"; para completo, & quot; e & quot; para o erro "u" para uma atualização de software disponível etc.
Eu criar a fila apenas antes de chamar o aplicativo Sync. exe e algo nele parece manter o Sync. exe vivo, quando eu fechar o aplicativo principal Sync. exe fecha também.
Essa implementação funciona bem em um dispositivo CE 4.2, mas não no dispositivo WM5 que tenho aqui.
Alguma idéia de como eu poderia modificar o código para WM5, ou devo considerar o uso de MSMQ ou algo parecido?
Ok, apenas no caso de alguém estar lendo isso ... a história até agora.
Alterei o código da fila de mensagens para usar o OpenNetCF. WindowsCE. Messaging. P2PMessageQueue e ainda tenho o mesmo problema. O problema ocorre quando o aplicativo de chamada abre uma Fila nomeada, inicia o segundo aplicativo como um processo e chama WaitForExit. O segundo aplicativo abre a mesma fila nomeada e envia mensagens que são recebidas pelo aplicativo de chamada. No entanto, quando o segundo aplicativo termina, ele nunca é realmente fechado, fazendo com que o WaitForExit bloqueie o aplicativo de chamada. Se eu parar o aplicativo de chamada, os dois aplicativos serão fechados.
Isso só ocorre se eu usar a mesma fila nomeada em ambos os aplicativos. É como se eles estivessem ligados através da fila? Isso tudo funcionou bem no PPC2003 e no CE4.2, mas no WM5.0 está causando uma dor de cabeça real! Socorro!!
Eu estou lutando contra um par estúpido de linhas de código com resultados muito estranhos. Estou executando o Win7.
O objetivo é iniciar um arquivo de comando (.cmd) a partir de um programa e esperar que este. cmd termine (com tempo limite).
Dentro do arquivo. cmd, há um comando TASKKILL. TASKKILL / F / T / IM CI. EXE.
Funciona perfeitamente ! Mas.
Se a tela de login é mostrada (o usuário está logado, mas a sessão está bloqueada), o TASKKILL está funcionando, mas o WaitForExit nunca termina, mesmo após o tempo limite.
Existe alguma boa explicação para isso e uma sugestão de solução alternativa? Desde já, obrigado !
Obrigado pelo seu tempo e sugestão.
No final, decidi reescrever meu próprio TASKKILL com um código C # muito simples, baseado em:
foreach (Process proc em Process. GetProcessByName ("CI")) (Ci é o nome do processo que eu quero matar)
E milagre! funciona ! Então, estou pensando que a TASKKILL faz muito mais do que apenas matar um processo.
Na verdade, meu bug agora está corrigido, então configurarei o thread como Respondido.
Obrigado pela sua leitura!
Marcado como Resposta dt51 sexta-feira, 8 de abril de 2016 14:42.
Todas as respostas.
Estou assumindo que o Tempo limite significa que você está definindo algum tempo para aguardar a saída do processo. Em caso afirmativo, tente deixar o processo para sair. Em vez de esperar algum período de tempo.
Para mais informações, leia este artigo: Método Process. WaitForExit ()
Editado por Sabah Shariq MVP, Moderador sexta-feira, 8 de abril de 2016 10:01.
Obrigado pelo seu tempo e resposta. Infelizmente, isso não funciona.
Eu estou com a idéia de que o TASKKILL vai causar alguma perturbação no método Process. WaitForExit. Na verdade, os dois estão trabalhando na mesma área.
Eu vou criar minha própria versão do TASKKILL de C #, mas não sou tão otimista. Te informaremos.
Se você tiver outra ideia, será bem-vindo!
Tem que ser principalmente acho que aqui. Além dos estados elevados / não elevados, há também o conceito de uma sessão interativa / não interativa.
Qual é o contexto exato em que o código está sendo executado?
Process. WaitForExit () tem este pequeno aviso:
& quot; Este método instrui o componente Process a aguardar uma quantidade infinita de tempo para que os manipuladores de processo e evento saiam. 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 encerrar o processo associado pode não ser tratada se o processo for gravado para nunca inserir seu loop de mensagem. & Quot;
Pode ser que enquanto a área de trabalho está bloqueada (o usuário não está logado corretamente), não há sessão interativa. Ou talvez nenhum dos loops de mensagens responda por padrão, pois processá-los custaria apenas recursos da CPU?
Ou talvez o contrário: não ter uma sessão interativa para começar pode permitir que o programa continue a ser executado. Esse código é executado em um serviço? Se não, que tal movê-lo para lá?
No comments:
Post a Comment