Powershell waitforexit não funciona
Powershell waitforexit não funciona
Eu estou tentando executar um programa do PowerShell, aguarde a saída e, em seguida, obter acesso ao ExitCode, mas não ter muita sorte. Não quero usar - Wait with Start-Process, já que preciso de algum processamento para continuar em segundo plano.
Aqui está um script de teste simplificado:
Executar este script fará com que o bloco de notas seja iniciado. Depois que isso for fechado manualmente, o código de saída será impresso e será iniciado novamente, sem usar a espera. Nenhum ExitCode é fornecido quando este é encerrado:
Eu preciso ser capaz de realizar processamento adicional entre iniciar o programa e esperar que ele saia, então não posso usar o - Wait. Alguma idéia de como posso fazer isso e ainda ter acesso à propriedade. ExitCode desse processo?
Duas coisas que você poderia fazer eu acho.
Crie o objeto System. Diagnostics. Process manualmente e ignore o Start-Process Execute o executável em uma tarefa em segundo plano (somente para processos não interativos!)
Veja como você pode:
Há duas coisas para lembrar aqui. Uma delas é adicionar o argumento - PassThru e duas é adicionar o argumento - Wait. Você precisa adicionar o argumento de espera devido a esse defeito connect. microsoft/PowerShell/feedback/details/520554/start-process-does-not-return-exitcode-property.
Depois de fazer isso, um objeto de processo é retornado e você pode examinar a propriedade ExitCode desse objeto. Aqui está um exemplo:
Se você executá-lo sem - PassThru ou - Wait, ele imprimirá nada.
Enquanto tentava a sugestão final acima, descobri uma solução ainda mais simples. Tudo o que precisei fazer foi armazenar em cache o identificador do processo. Assim que eu fiz isso, $ process. ExitCode funcionou corretamente. Se eu não fiz cache do identificador do processo, $ process. ExitCode era nulo.
Ou tente adicionar isso.
Usando esse código, você ainda pode permitir que o PowerShell cuide do gerenciamento de fluxos de saída / erro redirecionados, o que não é possível fazer usando System. Diagnostics. Process. Start () diretamente.
A opção '-Wait' pareceu bloquear para mim mesmo que o meu processo tivesse terminado.
Eu tentei a solução de Adrian e funciona. Mas eu usei o Wait-Process em vez de confiar em um efeito colateral de recuperar o identificador do processo.
Exemplo de uso.
Eu resolvi assim:
Eu redirecionei tanto a entrada, saída e erro e lidou com a leitura de fluxos de saída e erro. Essa solução funciona para o SDK 7- 8,1, tanto para o Windows 7 quanto para o Windows 8.
Eu tentei fazer uma classe que resolveria seu problema usando leitura de fluxo assíncrona, levando em consideração Mark Byers, Rob, stevejay respostas. Ao fazer isso, percebi que há um erro relacionado à leitura do fluxo de saída do processo assíncrono.
Você não pode fazer isso:
Você receberá System. InvalidOperationException: StandardOut não foi redirecionado ou o processo ainda não foi iniciado.
Então você precisa iniciar a leitura assíncrona 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 defini-los como assíncronos:
Então, algumas pessoas podem dizer que você só precisa ler o fluxo antes de defini-lo como assíncrono. Mas o mesmo problema ocorre. Haverá uma condição de corrida entre a leitura síncrona e o fluxo em modo assíncrono.
Não há como obter uma leitura assíncrona segura de um fluxo de saída de um processo na maneira real como "Process" e "ProcessStartInfo" foram projetados.
Provavelmente, é melhor usar a leitura assíncrona, como sugerido por outros usuários para o seu caso. Mas você deve estar ciente de que pode perder alguma informação 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 descartada (tentei as "soluções" das outras respostas).
Então decidi sugerir outra solução:
Este código depurado e funciona perfeitamente.
Introdução.
A resposta aceita atualmente não funciona (gera exceção) e há muitas soluções alternativas, mas nenhum código completo. Isto é, 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 o código completo com base em como eu quero usar o método Process. Start.
Eu usei-o para criar um diálogo de progresso em torno dos comandos do git. É assim que eu usei:
Em teoria, você também pode combinar stdout e stderr, mas eu não testei isso.
As outras soluções (incluindo EM0s) ainda estão em deadlock para meu aplicativo, devido a tempos limite internos e ao uso de StandardOutput e StandardError pelo aplicativo gerado. Aqui está o que funcionou para mim:
Editar: adicionada inicialização do StartInfo ao exemplo de código.
Este post talvez desatualizado, mas eu descobri a causa principal porque normalmente travar é devido ao estouro de pilha para a saída redirectStandard ou se você tiver redirectStandarderror.
Como os dados de saída ou os dados de erro são grandes, isso causará um tempo de interrupção, pois ainda está sendo processado por duração indefinida.
então, para resolver esse problema:
Eu acho que essa é uma abordagem simples e melhor (não precisamos do AutoResetEvent):
Eu estava tendo o mesmo problema, mas o motivo era diferente. No entanto, isso aconteceria no Windows 8, mas não no Windows 7. A linha a seguir parece ter causado o problema.
A solução foi NÃO desabilitar o UseShellExecute. Eu agora recebi uma janela popup do Shell, que é indesejada, mas muito melhor do que o programa esperando que nada de especial aconteça. Então eu adicionei a seguinte solução para isso:
Agora, a única coisa que me incomoda é por que isso está acontecendo no Windows 8 em primeiro lugar.
Eu sei que esta é a ceia de idade, mas, depois de ler esta página inteira, nenhuma das soluções estava funcionando para mim, embora eu não tenha tentado Muhammad Rehan como o código foi 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, eu acho que é algo a ver com o comprimento da saída antes de uma marca EOF.
De qualquer forma, a solução que funcionou para mim foi 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!
Depois de ler todos os posts aqui, resolvi a solução consolidada de Marko Avlijaš. No entanto, isso não resolveu todos os meus problemas.
Em nosso ambiente, temos um serviço do Windows que está programado para executar centenas de arquivos. bat. cmd. exe diferentes. etc arquivos que se acumularam ao longo dos anos e foram escritos por muitas pessoas diferentes e em diferentes estilos. Nós não temos controle sobre a escrita dos programas & amp; scripts, somos responsáveis apenas pelo agendamento, execução e geração de relatórios sobre sucesso / falha.
Então eu tentei praticamente todas as sugestões aqui com diferentes níveis de sucesso. A resposta de Marko foi quase perfeita, mas quando executada como um serviço, nem sempre captava stdout. Eu nunca cheguei ao fundo do por que não.
Powershell waitforexit não funciona
A sobrecarga WaitForExit () () () é usada para fazer o thread atual aguardar até que o processo associado termine. Este método instrui o componente Process a aguardar uma quantidade infinita de tempo para o processo sair. Isso pode fazer com que um aplicativo pare de responder. Por exemplo, se você chamar CloseMainWindow para um processo que tenha uma interface com o usuário, a solicitação para o sistema operacional finalizar o processo associado poderá não ser tratada se o processo for gravado para nunca inserir seu loop de mensagem.
Essa sobrecarga assegura que todo o processamento tenha sido concluído, incluindo o tratamento de eventos assíncronos para saída padrão redirecionada. Você deve usar essa sobrecarga após uma chamada para a sobrecarga WaitForExit (Int32) quando a saída padrão tiver sido redirecionada para manipuladores de eventos assíncronos.
Isto é claro para. O que faz você pensar que não espera que o processo do Note seja concluído? Quais são os sinais disso? Qual é a prova?
Processo p = new Process ();
MessageBox. Show (& quot; Agora o navegador deve estar fechado & quot;);
Exceto que você não consegue um objeto de processo que você possa usar. Se você tentar.
Dim myProc como novo processo ()
myProc = Process. Start (& quot; iexplore & quot ;, & quot; finance. yahoo/q/hp? s = & quot; símbolo +);
A Microsoft está realizando uma pesquisa online para entender sua opinião sobre o site da MSDN. Se você optar por participar, a pesquisa on-line será apresentada quando você sair do site do Msdn.
Powershell waitforexit não funciona
Eu tenho uma solução onde eu chamo um powershell em um novo segmento, então eu redireciono sua saída para uma caixa de texto.
Tudo funciona no meu computador de desenvolvimento, mas em outros computadores ele não :( Em outros computadores simplesmente não há saída do powershell, e o conhost. exe e o powershell. exe são executados em segundo plano mesmo se eu fechasse meu aplicativo. (No meu computador eles fecham com meu aplicativo.)
Por que funciona no meu comp e não nos outros?
Se eu alterar & quot; powershell. exe & quot; para & quot; cmd. exe & quot; então funciona em todos os lugares, mas eu preciso executar o powershell.
Eu tentei iniciar um cmd primeiro, depois executar o powershell de lá, mas perdi todas as saídas também.
Meu comp é Win10 x64, e os outros são Win7, Win8, 2012R2, etc.
Eu tentei compilá-lo em pelo menos 4-5 versão.
Obrigado por sua ajuda com antecedência!
Movido por qing__ segunda-feira, 5 de dezembro de 2016 02:33 relacionado a VB.
Todas as respostas.
Este fórum está discutindo o Visual Studio WPF / SL Designer, o Kit de Ferramentas de Automação de Guias do Visual Studio, a Documentação do Desenvolvedor e o Sistema de Ajuda e o Editor do Visual Studio.
Seu problema pode estar relacionado ao desenvolvimento de VB Vou mover este segmento para o fórum correspondente para uma resposta profissional.
Suporte da Comunidade MSDN.
Por favor, lembre-se de clicar em & quot; Marcar como Resposta & quot; as respostas que resolveram o seu problema e clicar em & quot; Desmarcar como Resposta & quot; se não. Isso pode ser benéfico para outros membros da comunidade que estiverem lendo este tópico. Se você tiver elogios ou reclamações ao Suporte do MSDN, entre em contato com o MSDNFSF @ microsoft.
Talvez outros computadores não tenham 4-5 neles. Ou talvez você queira dizer 4,5.
Talvez só seja executado corretamente no seu computador de desenvolvimento do Visual Studio. Você já o instalou no seu computador de desenvolvimento e não o executou a partir do Visual Studio?
Talvez seu aplicativo precise ser executado com Privilégios de administrador para que isso funcione. Você executa o Visual Studio com privilégios de administrador ao executar este aplicativo do Visual Studio?
Todos os outros sistemas x.64 também são? Você está compilando para CPU x.64 ou CPU AnyCPU ou x.86?
Talvez tente compilar para o 4.0 e ver se funciona em outros sistemas.
Eu quis dizer que tentei 4-5 versões diferentes de (incluindo 4.0, claro).
A notícia é que funciona em alguns outros computadores, mas apenas em computadores com o Windows 10 mais recente (ver 1607). Na ver 1511, não faz nada. Muito frustrante.
Eu tentei instalar o vstudio em um win8.1, mas o código não funcionou no modo de depuração ou compilado.
Eu tentei instalar o vstudio em outro win10, e o código funcionou no modo de depuração e compilado também.
Eu tentei com e sem privilégios de administrador, sem sorte.
O código foi compilado para x64 originalmente.
Como eu disse, toda vez que o aplicativo não funciona, o conhost. exe e o powershell. exe parecem travar, e eles não saem depois que eu saio do meu aplicativo.
Eu realmente não entendo porque esse moderador moveu seu problema para este fórum.
Parece ser algo como "Mova-se, não o meu problema".
No entanto, se o seu programa for executado no computador Windows A e não no Computador B, não haverá problemas no programa. Deve haver diferenças fora disso.
Principalmente esses problemas são feitos nos fóruns do Technet onde os administradores do sistema vivem.
Eu quis dizer que tentei 4-5 versões diferentes de (incluindo 4.0, claro).
A notícia é que funciona em alguns outros computadores, mas apenas em computadores com o Windows 10 mais recente (ver 1607). Na ver 1511, não faz nada. Muito frustrante.
Eu tentei instalar o vstudio em um win8.1, mas o código não funcionou no modo de depuração ou compilado.
Eu tentei instalar o vstudio em outro win10, e o código funcionou no modo de depuração e compilado também.
Eu tentei com e sem privilégios de administrador, sem sorte.
O código foi compilado para x64 originalmente.
Como eu disse, toda vez que o aplicativo não funciona, o conhost. exe e o powershell. exe parecem travar, e eles não saem depois que eu saio do meu aplicativo.
Verifique os logs de eventos do sistema nos sistemas nos quais ele não será executado para ver quais problemas podem estar ocorrendo.
Tente executar o visual studio com privilégios de administrador nos sistemas O visual studio está instalado no qual o programa trava quando executado no visual studio e veja se o programa será executado a partir da depuração do visual studio.
Coloque try catch around code e display messagebox se ocorrer uma exceção exibindo a exceção e o rastreamento de pilha de exceção.
Não tenho idéia do que isso faz e talvez seu aplicativo seja visto como vírus ou malware em alguns sistemas.
MVP da Microsoft (Visual Basic)
Não há absolutamente nenhum erro / aviso de log de eventos, eu já os verifiquei.
Tentei com priv admin.
Try-Catch não faz nada, porque não há mensagem de erro que eu possa pegar.
& quot; - ExecutionPolicy bypass - NoLogo - NoExit & quot; Simplesmente diz a Powershell como se iniciar.
Esse powershell é executado sem problemas fora do meu aplicativo com essas opções de linha de comando.
Algo ruim acontece quando o novo segmento ou processo é criado.
Você verificou se o Powershell está sendo executado exibindo a janela de comando? Você precisa determinar se o Powershell está sendo executado corretamente e não está esperando pela entrada da janela de comando.
MVP da Microsoft (Visual Basic)
Obrigado Paul, eu não tentei isso antes.
Em um ambiente de trabalho, ele exibe uma janela vazia com um cursor piscante e não aceita nenhuma entrada. A entrada é aceita a partir do aplicativo e a saída é exibida na janela de texto do aplicativo.
Em um ambiente que não funciona, ele exibe a janela, mas o powershell é executado dentro dela e aceita a entrada da janela de comando, e a saída também é exibida na janela de comando.
Portanto, o powershell é executado, mas o redirecionamento não funciona por alguns motivos.
Você pode me ajudar por quê?
Eu não sou conhecido com o Powershell, mas talvez este código em nosso site possa ajudá-lo para a parte de redirecionamento.
Obrigado Paul, eu não tentei isso antes.
Em um ambiente de trabalho, ele exibe uma janela vazia com um cursor piscante e não aceita nenhuma entrada. A entrada é aceita a partir do aplicativo e a saída é exibida na janela de texto do aplicativo.
Em um ambiente que não funciona, ele exibe a janela, mas o powershell é executado dentro dela e aceita a entrada da janela de comando, e a saída também é exibida na janela de comando.
Portanto, o powershell é executado, mas o redirecionamento não funciona por alguns motivos.
Você pode me ajudar por quê?
Você já tentou adicionar uma chamada para WaitForExit?
MVP da Microsoft (Visual Basic)
Nesse caso, o aplicativo aguarda para sempre e o formulário nem aparece até que eu mate o processo conhost. exe.
Nesse caso, o aplicativo aguarda para sempre e o formulário nem aparece até que eu mate o processo conhost. exe.
Como sobre como remover - NoExit dos comandos de inicialização.
MVP da Microsoft (Visual Basic)
Nesse caso, foi interessante.
O. Arguments agora é & quot; - ExecutionPolicy bypass - NoLogo - NoExit get-process & quot ;.
Eu removi - NoExit, e neste caso ambos os sistemas fazem o mesmo: powershell começa, e get-process envia sua saída para a janela de formulário, então MyProcess_ErrorDataReceived exibe um & quot; Error: & quot ;, porque o powershell saiu.
Portanto, neste caso, o PowerShell também poderia redirecionar sua saída para o sistema não funcional, mas depois saiu.
Se eu colocar de volta - NoExit, nada aparece (até mesmo a saída de get-process). Muito estranho.
Nesse caso, foi interessante.
O. Arguments agora é & quot; - ExecutionPolicy bypass - NoLogo - NoExit get-process & quot ;.
Eu removi - NoExit, e neste caso ambos os sistemas fazem o mesmo: powershell começa, e get-process envia sua saída para a janela de formulário, então MyProcess_ErrorDataReceived exibe um & quot; Error: & quot ;, porque o powershell saiu.
Portanto, neste caso, o PowerShell também poderia redirecionar sua saída para o sistema não funcional, mas depois saiu.
Se eu colocar de volta - NoExit, nada aparece (até mesmo a saída de get-process). Muito estranho.
O Powershell executa o comando até a conclusão?
Ainda não vi um exemplo que use - NoExit. Isso só impede que o Powershell termine, o que você provavelmente não quer. Você também pode tentar colocar WaitForExit após as instruções ReadLine para ver se faz alguma diferença.
MVP da Microsoft (Visual Basic)
Não, quero que o Powershell continue em execução, porque normalmente (em vez do comando get-process) eu incluo os cmdlets do Shell de Gerenciamento do Exchange no final da lista. Parâmetros. E isso funciona no meu computador.
Você pode tentar este código no build 1607 e em Windows mais antigos?
A Microsoft está realizando uma pesquisa online para entender sua opinião sobre o site da MSDN. Se você optar por participar, a pesquisa on-line será apresentada quando você sair do site do Msdn.
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.
Veja o exemplo de código para a propriedade ExitCode.
para confiança total para o chamador imediato. Este membro não pode ser usado por código parcialmente confiável.
Processo . Método WaitForExit.
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.
Define o período de tempo para aguardar a saída do processo associado e bloqueia o thread atual de execução até que o tempo tenha transcorrido ou o processo tenha sido encerrado. Para evitar o bloqueio do segmento atual, use o evento Exited.
Para exemplos de código, consulte as páginas de referência de propriedade StandardError e ExitCode.
Assembly: System (no System. dll)
Instrui o componente Process a aguardar indefinidamente que o processo associado seja encerrado.
Instrui o componente Processo a aguardar o número especificado de milissegundos para o processo associado sair.
A sobrecarga WaitForExit () () () é usada para fazer o thread atual aguardar até que o processo associado termine. Este método instrui o componente Process a aguardar uma quantidade infinita de tempo para o processo sair. Isso pode fazer com que um aplicativo pare de responder. Por exemplo, se você chamar CloseMainWindow para um processo que tenha uma interface com o usuário, a solicitação para o sistema operacional finalizar o processo associado poderá não ser tratada se o processo for gravado para nunca inserir seu loop de mensagem.
Essa sobrecarga assegura que todo o processamento tenha sido concluído, incluindo o tratamento de eventos assíncronos para saída padrão redirecionada. Você deve usar essa sobrecarga após uma chamada para a sobrecarga WaitForExit (Int32) quando a saída padrão tiver sido redirecionada para manipuladores de eventos assíncronos.
Isto é claro para. O que faz você pensar que não espera que o processo do Note seja concluído? Quais são os sinais disso? Qual é a prova?
Processo p = new Process ();
MessageBox. Show (& quot; Agora o navegador deve estar fechado & quot;);
Exceto que você não consegue um objeto de processo que você possa usar. Se você tentar.
Dim myProc como novo processo ()
myProc = Process. Start (& quot; iexplore & quot ;, & quot; finance. yahoo/q/hp? s = & quot; símbolo +);
A Microsoft está realizando uma pesquisa online para entender sua opinião sobre o site da MSDN. Se você optar por participar, a pesquisa on-line será apresentada quando você sair do site do Msdn.
Comments
Post a Comment