Sunday 25 March 2018

Powershell processstartinfo waitforexit


Powershell processstartinfo waitforexit
Obter através da App Store Leia esta publicação em nosso aplicativo!
Como faço para redirecionar a saída do Powershell.
Tenho uma estrutura de instalador personalizada escrita há muito tempo. Dentro disso, eu posso executar "tarefas". Recentemente tive que adicionar uma tarefa para executar um script do PowerShell. Agora, mesmo que a tarefa esteja escrita em C #, não posso invocar os comandos no script do PowerShell diretamente. Isso, infelizmente, está fora da mesa.
Em suma, eu quero invocar um executável do PowerShell a partir de C # e redirecionar sua saída de volta para minha aplicação. Aqui está o que fiz até agora:
Eu posso invocar com sucesso o PowerShell usando o seguinte código (de um projeto de teste que criei):
Meus manipuladores para a saída redirecionada nunca são chamados:
Estou bastante confiante de que o script está sendo executado. Agora eu tenho apenas um script de teste que está exibindo os conteúdos do PATH.
Eu testei isso de uma instância do PowerShell e ele é executado corretamente.
O que posso fazer para obter a saída do PowerShell para redirecionar para o meu código C #? Eu não quero confiar nos scripts que eu executarei para lidar com seu próprio registro. Prefiro reunir a sua produção e lidar com isso dentro do mecanismo de log da estrutura.
EDIT Realizado Eu deixei o loop estranho para aguardar a saída nesse exemplo de código. Eu tive o processo "WaitForExit":
Usando a sugestão da MiniBill. Eu criei o seguinte código snippit:
Isso lida com a boa performance. Ele está cortando minhas linhas em 80 caracteres :(, mas eu posso viver com isso a menos que outra pessoa possa fornecer uma sugestão para corrigir isso!

Powershell processstartinfo waitforexit
Obter através da App Store Leia esta publicação em nosso aplicativo!
Obtendo ExitCode usando Start-Process e WaitForExit em vez de - Wait.
Estou tentando executar um programa do PowerShell, aguardar a saída, depois ter acesso ao ExitCode, mas não ter muita sorte. Eu não quero usar - Aguarde com o Processo de Início, como eu preciso de algum processamento para continuar em segundo plano.
Aqui está um script de teste simplificado:
A execução deste script fará com que o bloco de notas seja iniciado. Depois disso, é fechado manualmente, o código de saída será impresso, e ele será iniciado de novo, sem usar - wait. Nenhum ExitCode é fornecido quando isso é encerrado:
Eu preciso ser capaz de executar um processamento adicional entre iniciar o programa e aguardá-lo para sair, então eu não posso fazer uso de "Esperar". 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 (apenas para processos não interativos).
Veja como você poderia fazer:
Há duas coisas para lembrar aqui. Um é adicionar o argumento - PassThru e dois é adicionar o argumento - Wait. Você precisa adicionar o argumento de espera por causa desse defeito, connect. microsoft/PowerShell/feedback/details/520554/start-process-does-not-return-exitcode-property.
Depois de fazer isso, um objeto de processo é passado de volta e você pode observar a propriedade ExitCode desse objeto. Aqui está um exemplo:
Se você executá-lo sem - PassThru ou - Wait, ele não imprimirá nada.
Enquanto tentava a sugestão final acima, descobri uma solução ainda mais simples. Tudo o que eu tinha que fazer era armazenar em cache o identificador do processo. Assim que eu fiz isso, $ process. ExitCode funcionou corretamente. Se eu não escondeu o process handle, $ process. ExitCode era nulo.
Ou tente adicionar isso.
Ao usar este código, você ainda pode permitir que o PowerShell se ocupe de gerir os fluxos de saída / erro redirecionados, o que você não pode fazer usando System. Diagnostics. Process. Start () diretamente.
A opção '' Esperar 'parecia me bloquear mesmo que meu processo tivesse terminado.
Eu tentei a solução de Adrian e funciona. Mas eu usei Wait-Process em vez de confiar em um efeito colateral de recuperar o process handle.

Obtendo System. Diagnostics. ProcessStartInfo para funcionar.
CCIS_Huntington (3 comentários) Learnctx (2 comentários)
O que significa ser "Always On"?
A sua nuvem está sempre ligada? Com uma nuvem Always On, você não terá que se preocupar com o tempo de inatividade para manutenção ou atualização de código de aplicativo de software, garantindo que sua linha de fundo não seja afetada.
Publicação destacada.
Você será compatível com GDPR até 5/28/2018?
GDPR? Esse é um regulamento para a União Européia. Mas, se você coletar dados de clientes ou funcionários dentro da UE, então você precisa saber sobre o GDPR e certificar-se de que sua organização está em conformidade até maio de 2018. Confira nossa lista de verificação de preparação para garantir que você esteja no bom caminho hoje!

Powershell processstartinfo waitforexit
Estou executando um aplicativo perfcalc. exe enviando alguns parâmetros através de "System. Diagnostics. Process". O objetivo é, eu quero receber de volta o código de saída e o padrão de saída. Está funcionando corretamente. MAS, eu também quero adicionar um limite de tempo limite, por isso, se o processo levar mais de 30 minutos, ele terminará automaticamente o trabalho. A razão pela qual eu preciso disso, o applicaiton perfcalc. exe, por vezes, get-halt ou mantenha o processo, desta forma, o código total não pode ser executado e não recebo nenhum email de notificação.
$ objProcess = New-Object System. Diagnostics. Process.
$ objProcess. StartInfo = New-Object System. Diagnostics. ProcessStartInfo.
$ objProcess. StartInfo. Arguments = & quot; - tSPDF - m \\ srvr098 \ reports \ calc. pdf & quot;
Editado por TekFinder sexta-feira, 06 de junho de 2014 às 17:04.
$ objProcess. WaitForExit () vai bloquear seu processo de script, esperando que ele termine.
Isso funciona para você?
Editado por mjolinor sexta-feira, 6 de junho de 2014 17:48 Marcado como Resposta AnnaWY Moderador quarta-feira, 18 de junho de 2014 3:26.
Adicionado try catch - apenas para evitar erros.
Regards Chen V [MCTS SharePoint 2010]
Marcado como resposta por AnnaWY Moderador quarta-feira, 18 de junho de 2014 3:26.
Todas as respostas.
Isso pode dar alguma idéia.
para parar o serviço executando mais de 30 minutos.
Regards Chen V [MCTS SharePoint 2010]
Isso pode dar alguma idéia.
para parar o serviço executando mais de 30 minutos.
Regards Chen V [MCTS SharePoint 2010]
Na verdade, o problema é que o aplicativo perfcalc. exe às vezes está segurando meu processo por tempo indeterminado. Então não tenho chance de sair do porão e usar seu código para encontrar & amp; mate o processo. Se eu quiser usar sua solução, então eu tenho que executar seu código separadamente. Estou procurando por uma solução se eu puder adicionar o limite de tempo dentro da definição do objeto New-Object System. Diagnostics. Process? Como $ objProcess. TimeOut etc. É possível?
Editado por TekFinder sexta-feira, 06 de junho de 2014 5:22 PM.
$ objProcess. WaitForExit () vai bloquear seu processo de script, esperando que ele termine.
Isso funciona para você?
Editado por mjolinor sexta-feira, 06 de junho de 2014 5:48 PM Marcado como resposta por AnnaWY Moderador quarta-feira, 18 de junho de 2014 3:26.
Isso irá bloqueá-lo. Testando seu código agora.
Regards Chen V [MCTS SharePoint 2010]
Desculpe, não atualizei a página antes de publicar.
Agora você pode testar o código mjolinor.
Uma sugestão é o que acontece se o processo sair durante o start-sleep 5 segundos - Stop-Process irá gerar erro. Mas vale a pena testar.
Regards Chen V [MCTS SharePoint 2010]
Você pode fazer uma tentativa para isso, suponho. Parece que seria discutível se o processo já tivesse saído.
Editado por mjolinor sexta-feira, 06 de junho de 2014 18:00.
Adicionado tentar catch - Apenas para evitar erros.
Regards Chen V [MCTS SharePoint 2010]
Marcado como resposta por AnnaWY Moderador quarta-feira, 18 de junho de 2014 3:26.
Desculpe, não atualizei a página antes de publicar.
Agora você pode testar o código mjolinor.
Uma sugestão sobre o que acontece se o processo sair durante o Início-Sair 5 segundos - Stop-Process lançará erro. Mas vale a pena testar.
Regards Chen V [MCTS SharePoint 2010]
Eu não acho que vai dar um erro. Está novamente verificando se o processo ainda está sendo executado fora do loop do temporizador, antes que ele tente parar o processo.
Se ele sair durante o último ciclo de sono, esse teste falhará e o processo de parada não será executado.
A Microsoft está realizando uma pesquisa on-line para entender sua opinião sobre o site da Technet. Se você optar por participar, a pesquisa on-line será apresentada quando você sair do site da Technet.

Propriedade Process. StandardError.
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.
Obtém um fluxo usado para ler a saída de erro do aplicativo.
Assembly: System (no System. dll)
Valor da propriedade.
Um StreamReader que pode ser usado para ler o fluxo de erros padrão do aplicativo.
O fluxo StandardError foi aberto para operações de leitura assíncronas com BeginErrorReadLine.
Quando um Processo grava texto em seu fluxo de erro padrão, esse texto normalmente é exibido no console. Ao redirecionar o fluxo StandardError, você pode manipular ou suprimir a saída de erro de um processo. Por exemplo, você pode filtrar o texto, formatá-lo de maneira diferente ou gravar a saída no console e em um arquivo de log designado.
Para usar StandardError, você deve definir ProcessStartInfo. UseShellExecute como falso e você deve definir ProcessStartInfo. RedirectStandardError como verdadeiro. Caso contrário, a leitura do fluxo StandardError gerará uma exceção.
O fluxo StandardError redirecionado pode ser lido de forma síncrona ou assíncrona. Métodos como Read, ReadLine e ReadToEnd executam operações de leitura síncrona no fluxo de saída de erro do processo. Essas operações de leitura síncrona não são concluídas até que o Processo associado escreva em seu fluxo StandardError ou encerre o fluxo.
Em contraste, BeginErrorReadLine inicia operações de leitura assíncronas no fluxo StandardError. Este método habilita um manipulador de eventos designado para a saída do fluxo e retorna imediatamente ao chamador, o que pode executar outro trabalho enquanto a saída do fluxo é direcionada para o manipulador de eventos.
As operações de leitura síncrona introduzem uma dependência entre a leitura do responsável pela chamada do fluxo StandardError e a gravação do processo filho nesse fluxo. Essas dependências podem resultar em condições de impasse. Quando o chamador lê o fluxo redirecionado de um processo filho, ele depende do filho. O chamador aguarda na operação de leitura até que o filho grave no fluxo ou feche o fluxo. Quando o processo filho grava dados suficientes para preencher o fluxo redirecionado, ele depende do pai. O processo filho aguarda a próxima operação de gravação até que o pai lê do fluxo completo ou fecha o fluxo. A condição de deadlock resulta quando o processo do chamador e filho aguardam um para o outro para concluir uma operação, e nenhum deles pode prosseguir. Você pode evitar deadlocks avaliando dependências entre o chamador e o processo filho.
O seguinte código C #, por exemplo, mostra como ler de um fluxo redirecionado e aguarde o processo filho sair.
O exemplo de código evita uma condição de bloqueio chamando p. StandardError. ReadToEnd antes de p. WaitForExit. Uma condição de impasse pode resultar se o processo pai chama p. WaitForExit antes de p. StandardError. ReadToEnd e o processo filho grava texto suficiente para preencher o fluxo redirecionado. O processo pai esperaria indefinidamente para que o processo filho saísse. O processo filho esperaria indefinidamente para o pai ler do fluxo completo do StandardError.
Há um problema semelhante ao ler todo o texto da saída padrão e dos fluxos de erro padrão. O seguinte código C #, por exemplo, executa uma operação de leitura nos dois fluxos.
O exemplo de código evita a condição de bloqueio executando operações de leitura assíncronas no fluxo StandardOutput. Um estado de impasse resulta se o processo pai chamar p. StandardOutput. ReadToEnd seguido de p. StandardError. ReadToEnd e o processo filho escreve texto suficiente para preencher o fluxo de erros. O processo pai aguardaria indefinidamente o processo filho para fechar o fluxo StandardOutput. O processo filho esperaria indefinidamente para o pai ler do fluxo completo do StandardError.
Você pode usar operações de leitura assíncronas para evitar essas dependências e seu potencial de impasse. Alternativamente, você pode evitar a condição de bloqueio criando dois tópicos e lendo a saída de cada fluxo em um segmento separado.
Você não pode misturar operações de leitura assíncronas e síncronas em um fluxo redirecionado. Uma vez que o fluxo redirecionado de um Processo é aberto em modo assíncrono ou síncrono, todas as operações de leitura adicionais nesse fluxo devem estar no mesmo modo. Por exemplo, não siga BeginErrorReadLine com uma chamada para ReadLine no fluxo StandardError ou vice-versa. No entanto, você pode ler dois fluxos diferentes em modos diferentes. Por exemplo, você pode chamar BeginOutputReadLine e, em seguida, chamar ReadLine para o fluxo StandardError.
O exemplo a seguir usa o comando net use junto com um argumento fornecido pelo usuário para mapear um recurso de rede. Em seguida, ele lê o fluxo de erro padrão do comando net e o grava no console.
para confiança total para o chamador imediato. Este membro não pode ser usado por código parcialmente confiável.

Powershell processstartinfo waitforexit
Estou tentando iniciar um processo e pegar o StandardOutput e o StandardError usando EventHandlers e BeginOutputReadLine. Eu posso iniciar o processo, mas recebo.
Exceção chamando & quot; BeginOutputReadLine & quot; com "0" argumento (s): "Não é possível misturar a operação síncrona e assíncrona no fluxo de processo. & quot;
Aqui está a minha função de lançamento:
Estou violando o modelo de Threading Powershell? Obrigado!
Estou tentando iniciar um processo e pegar o StandardOutput e o StandardError usando EventHandlers e BeginOutputReadLine. Posso iniciar o processo, mas eu consigo.
Exceção chamando & quot; BeginOutputReadLine & quot; com "0" argumento (s): "Não é possível misturar a operação síncrona e assíncrona no fluxo de processo. & quot;
A mensagem de erro está informando o que você está fazendo de errado.
Você não pode atribuir funções a um processo síncrono. As funções não são delegados, então não funcionará. Você precisa usar um modelo de evento ou usar a variação do asynch.
Use isso como um modelo:
Marcado como resposta por Oliver Lipkau Moderador quarta-feira, 12 de outubro de 2011 2:32.
Todas as respostas.
Eu acredito que você tenha alguns erros de digitação em seu código. Eu sou a pessoa mais humilde que você já conheceu.
Estou tentando iniciar um processo e pegar o StandardOutput e o StandardError usando EventHandlers e BeginOutputReadLine. Posso iniciar o processo, mas eu consigo.
Chamada de exceção "BeginOutputReadLine & quot; com "0" argumento (s): "Não é possível misturar a operação síncrona e assíncrona no fluxo de processo. & quot;
A mensagem de erro está informando o que você está fazendo de errado.
Você não pode atribuir funções a um processo síncrono. As funções não são delegados, então não funcionará. Você precisa usar um modelo de evento ou usar a variação do asynch.
Use isso como um modelo:
Marcado como resposta por Oliver Lipkau Moderador quarta-feira, 12 de outubro de 2011 2:32.
Ok, eu não entendi a implementação do BeginOutputReadline. Eu pensei que isso funcionaria com. WaitForExit - olhando para ele agora, eu vejo por que ele não está.
Em VB, eu sei como 1) gerar threads para lidar com isso e eu sei que você pode colocar o processo em um loop 2) até que seja concluído como uma maneira de lidar com isso.
Eu não quero fazer # 2. Existe uma maneira multithreaded ou assíncrona para ler a saída de um determinado processo como o processo está gerando?
Ok, eu não entendi a implementação do BeginOutputReadline. Eu pensei que isso funcionaria com. WaitForExit - olhando para ele agora, eu vejo por que ele não está.
Em VB, eu sei como 1) gerar threads para lidar com isso e eu sei que você pode colocar o processo em um loop 2) até que seja concluído como uma maneira de lidar com isso.
Eu não quero fazer # 2. Existe uma maneira multithreaded ou assíncrona para ler a saída de um determinado processo como o processo está gerando?
Na verdade, a menos que você queira criar um evento delegado. Mas, então, isso é o PowerShell, não é o VB.
Você pode começar aqui e ver se o evento que você está procurando pode ser "conectado"
Ajude Register-ObjectEvent - full.
Editado por jrv terça-feira, 27 de setembro de 2011 15:22.
A resposta marcada não resolve o problema com o qual o OP está lutando - isto é, redirecionando StdErr e StdOut e sofre com o bug de conflito discutido aqui:
Uma condição de impasse pode resultar se o processo pai chamar p. WaitForExit antes de p. StandardOutput. ReadToEnd e o processo filho grava texto suficiente para preencher o fluxo redirecionado. O processo pai esperaria indefinidamente para que o processo filho saísse. O processo infantil esperaria indefinidamente para o pai ler do fluxo de StandardOutput completo. & Quot;
Eu também estou tentando a melhor resposta para fazer isso funcionar no Powershell, mas todos os exemplos de código que estou executando, que utilizam System. Diagnostics. Process em powersehll são replicando o impasse nesta implementação ou não estão redirecionando stderr e stdout.
A solução em que estou indo usa o cmdlet Start-Process da seguinte maneira:
Não é uma ótima solução, pois só redirecionará stdout e stderr para um arquivo de texto. mas funcionará o tempo todo e redirecionará stdout e stderr.
Se nós vamos usar a saída redirecionada, não usaremos a espera. Esse foi o design do CreateProcess desde NT4.
O uso de arquivos para capturar a saída funcionará porque um fluxo é anexado que publica uma leitura constante para o fluxo de saída. O fluxo de saída nunca é suspenso. Yu não pode fazer isso em um loop de código. O fluxo corre o sistema do sistema do pecado Eu acredito e sempre terei uma chance de ler. A espera está no seu segmento para que você não consiga ler manualmente. É um impasse como afirmado.
O uso da leitura do console é geralmente porque estamos à procura de um prompt. Nesse caso, nunca esperamos a conclusão. O código ZTHe provavelmente será enviado para 'quit' e nós iremos verificar o processo e girá-lo até que ele seja desligado.
A questão aqui é que não podemos gerar um Thead. Em VB ou C #, C, usaríamos apenas threads de separação para IO e um para espera. Melhor ainda, eu usaria um semáforo, pois pode dinamicamente capturar um desligamento inesperado.
Talvez a próxima versão do PowerSHell tenha boas possibilidades de multithreading.
Esta é apenas mais uma lição de que a Powershell é uma linguagem de script, não uma linguagem de programação, e tão poderosa quanto é, existem armadilhas.
O código de exemplo da Microsoft simplesmente não é abrangente o suficiente para um hack de powershell perceber que não podem chegar lá a partir daqui. Foi o que me atrapalhou e também acredito no OP, porque havia alguma expectativa de que BeginOutputReadline implementasse a magia para que ele funcionasse threads que resolveriam o problema de bloqueio. Não, então acabamos aqui.
E uma pequena correção para o meu código - deixei o sinalizador - que é necessário para o resto do código funcionar:
Esta é apenas mais uma lição de que a Powershell é uma linguagem de script, não uma linguagem de programação, e tão poderosa quanto é, existem armadilhas.
O código de exemplo da Microsoft simplesmente não é abrangente o suficiente para um hack de powershell perceber que não podem chegar lá a partir daqui. Foi o que me atrapalhou e também acredito no OP, porque havia alguma expectativa de que BeginOutputReadline implementasse a magia para que ele funcionasse threads que resolveriam o problema de bloqueio. Não, então acabamos aqui.
E uma pequena correção para o meu código - deixei o sinalizador - que é necessário para o resto do código funcionar:
Certo. O PowerShell é propositadamente limitado para torná-lo mais seguro para a população em geral e para reduzir os problemas que ocorrem com as linguagens compiladas.
Sim - o sinalizador de espera ajudaria, pois o arquivo pode não ter terminado o spool antes do programa encerrar.
Start-Process é um wrapper fraco na API do processo, mas protege os desavisados ​​dos deadlocks porque você não pode redirecionar a entrada, exceto de um arquivo.
Você não precisa - venha para redirecionar. Você precisa de aguardar os arquivos e como uma maneira fácil de detecção de terminação. Usando a API, isso tem que ser feito consultando o objeto de processo ou extraindo a saída e aguardando que o processo envie sua mensagem de término e então gire o status.
Isso é muito demais para os scripts de administração e, como você apontou, não os levará a nenhum problema.
Olá, tenho feito muita leitura e tropeçando com esse tópico, percebi que tenho um problema semelhante. Estou tendo dificuldade em receber meus feeds de Saída e meus erros para ler da minha janela do console ISE. Mesmo depois de ler tudo o que foi escrito acima e analisar o local de ajuda do MSDN, ainda não consigo ver o erro nos meus caminhos. Eu entendo que você não pode ler de forma assíncrona e síncrona ao mesmo tempo e que, se você chamar um antes do outro, eles ficarão impassíveis, mas ainda não consigo ver onde meu erro é porque eu não obtenho nenhum resultado. Meu código está abaixo. Se algum de vocês souber de algum grande recurso para aprender PowerShell, por favor me avise, eu poderia usar para aprender um pouco mais.
Apenas um estudante de tecnologia, é tudo!
Desculpe, mas este tópico foi fechado por 5 anos. Você precisa iniciar seu próprio tópico.
Olá, tenho feito muita leitura e tropeçando com esse tópico, percebi que tenho um problema semelhante. Estou tendo dificuldade em obter meus feeds de saída e meus erros para ler na janela do meu console ISE. Mesmo depois de ler tudo o que foi escrito acima e olhar para o local de ajuda do MSDN, ainda não consigo ver o erro em meus caminhos. Eu entendo que você não pode ler de forma assíncrona e síncrona ao mesmo tempo e que, se você chamar um antes do outro, eles ficarão impassíveis, mas ainda não consigo ver onde meu erro é porque eu não obtenho nenhum resultado. Meu código está abaixo. Se algum de vocês sabe de grandes recursos na aprendizagem do PowerShell, por favor me avise, eu poderia usar para aprender um pouco mais.
Apenas um estudante de tecnologia, é tudo!
Oi, você encontrou a solução? Eu tenho o mesmo problema :(
A Microsoft está realizando uma pesquisa on-line para entender sua opinião sobre o site da Technet. Se você optar por participar, a pesquisa on-line será apresentada quando você sair do site da Technet.

No comments:

Post a Comment