Thursday 17 August 2017

Aguarde Emxter In Powershell


Estou tentando executar um programa do PowerShell, aguarde a saída, em seguida, obter acesso ao ExitCode, mas não ter muita sorte. Eu não quero usar - Wait com Start-Process, como eu preciso de algum processamento para continuar em segundo plano. Heres um script de teste simplificado: Executar este script fará com que o bloco de notas seja iniciado. Depois que este for fechado manualmente, o código de saída será impresso, e ele será iniciado novamente, sem usar - wait. Nenhum ExitCode é fornecido quando isso é sair: Eu preciso ser capaz de executar o processamento adicional entre iniciar o programa e à espera dele sair, então eu não posso fazer uso de - Wait. Qualquer idéia de como eu posso fazer isso e ainda ter acesso à propriedade. ExitCode a partir deste processo pediu 21 abr às 19:23 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 deste defeito connect. microsoft/PowerShell/feedback/details/520554/start-process-does-not-return-exitcode-property Depois de fazer esse objeto de um processo é passado para trás e você pode olhar Na propriedade ExitCode desse objeto. Aqui está um exemplo: Se você executá-lo sem - PassThru ou - Wait, ele vai imprimir nada. Usando o Windows PowerShell Jobs Resumo: Microsoft Scripting Guy, Ed Wilson, mostra um trecho de seu novo livro passo a passo sobre o uso do Windows Trabalhos do PowerShell. O Microsoft Scripting Guy, Ed Wilson, está aqui. Hoje eu quero compartilhar uma parte do meu novo Microsoft Press Windows PowerShell 3.0 passo a passo livro. Este livro está disponível agora para pré-encomenda. Usando trabalhos do Windows PowerShell Você pode iniciar um novo trabalho do Windows PowerShell usando o cmdlet Start-Job. O comando a ser executado como um trabalho é colocado em um bloco de script, e os trabalhos são nomeados seqüencialmente Job1, Job2 hellip Isso é mostrado aqui. PS C: gt Start-Job - ScriptBlock Id Nome PSJobTypeName Estado HasMoreData Localização 8212 8212 8212821282128212 82128211 8212821282128211 821282128211 10 Job10 BackgroundJob execução True localhost PS C: gt As tarefas recebem IDs de trabalho que também são numeradas seqüencialmente. O primeiro trabalho criado em um console do Windows PowerShell é sempre o ID do trabalho 1. Você pode usar o ID do trabalho ou o nome do trabalho para obter informações sobre o trabalho. Isso é visto aqui. PS C: GT Get-Job - Name job10 Id Nome PSJobTypeName Estado HasMoreData Localização 8212 8212- 8212821282128212- 82128211 8212821282128211 821282128211 10 Job10 BackgroundJob Concluído Verdadeiro localhost PS C: GT Get-Job - Id 10 Id Nome PSJobTypeName Estado HasMoreData Localização 8212 8212- 8212821282128212 - 82128211 8212821282128211 821282128211 10 Job10 BackgroundJob Completed True localhost Uma vez que você ver que o trabalho foi concluído, você pode receber o trabalho. O cmdlet Receive-Job retorna as mesmas informações que retornam se uma tarefa não for usada. A saída Job1 aqui (truncada para economizar espaço). PS C: gt Trabalho de Recebimento-Nome job10 Processadores NPM (K) PM (K) WS (K) CPU (s) VM (M) Id ProcessName 82128212- 82128212 82128211 82128211 82128211 82128212 8212 8212821282128211 62 9 1672 6032 80 0,00 1408 apdproxy 132 9 2316 5632 62 1364 atieclxx 122 7 1716 4232 32 948 atiesrxx 114 9 14664 15372 48 1492 audiodg 556 62 53928 5368 616 3,17 3408 CCC 58 8 2960 7068 70 0,19 928 conhost 32 5 1468 3468 52 0,00 5068 conhost 784 14 3284 5092 56 416 csrss 529 27 2928 17260 145 496 csrss 182 13 8184 11152 96 0.50 2956 DCPSysMgr 135 11 2880 7552 56 2056 DCPSysMgrSvc 8230 (saída truncada) Uma vez que um trabalho foi recebido, que é mdash os dados se foram, a menos que você salvá-lo para uma variável. O código a seguir ilustra esse conceito. O que pode ser confuso sobre isso é que o trabalho ainda existe eo cmdlet Get-Job continua a recuperar informações sobre o trabalho. Isso é visto aqui. PS C: gt Get-Job - Id 10 Id Nome PSJobTypeName Estado HasMoreData Localização 8212 8212- 8212821282128212- 82128211 8212821282128211 821282128211 10 Job10 BackgroundJob Concluído Falso localhost Como uma prática recomendada, use o cmdlet Remove-Job para eliminar restos de trabalhos concluídos quando são Terminar usando o objeto de trabalho. Isso evitará confusão sobre trabalhos ativos, trabalhos concluídos e trabalhos em espera para serem processados. Depois que um trabalho foi removido, o cmdlet Get-Job retorna um erro se você tentar recuperar informações sobre o trabalho mdash porque ele não existe mais. Isto é ilustrado aqui. PS C: gt Remove-Trabalho-Nome job10 PS C: gt Get-Job - Id 10 Get-Job. O comando não pode localizar um trabalho com o ID de tarefa 10. Verifique o valor do parâmetro Id e, em seguida, tente o comando novamente. Na linha: 1 char: 1 Get-Job - Id 10 CategoryInfo. ObjectNotFound: (10: Int32) Get-Job, PSArgumentExcepção FullyQualifiedErrorId. JobWithSpecifiedSessionNotFound, Microsoft. PowerShell. Commands. GetJobCommand Ao trabalhar com os cmdlets de trabalho, eu gosto de dar aos trabalhos seu próprio nome. Um trabalho que retorna objetos de processo através do cmdlet Get-Process pode ser chamado getProc. Um esquema de nomeação contextual funciona melhor do que tentando manter controle de nomes como Job1 ou Job2. Não se preocupe em tornar seus nomes de trabalho muito longos, porque você pode usar caracteres curinga para simplificar o requisito de digitação. Quando você receber o trabalho, certifique-se armazenar os objetos retornados em uma variável. Isso é mostrado aqui. PS C: GT Start-Job - Name GetProc - ScriptBlock Id Nome PSJobTypeName Estado HasMoreData Localização 8212 8212- 8212821282128212- 82128211 8212821282128211 821282128211 12 GetProc BackgroundJob Correr Verdadeiro localhost PS C: GT Get-Job - Name obter Id Nome PSJobTypeName Estado HasMoreData Localização 8212 8212 - 8212821282128212- 82128211 8212821282128211 821282128211 12 getProc BackgroundJob Concluído True localhost PS C: gt procObj Receber-Trabalho-Nome obter PS C: gt Depois de ter o objeto retornado em uma variável, você pode usar o objeto com outros cmdlets do Windows PowerShell. Uma coisa a ter em mente é que o objeto é desserializado. Isso é visto aqui onde eu uso gm como um alias para o cmdlet Get-Member. PS C: gt procObj gm TipoName: Deserialized. System. Diagnostics. Process Isso significa que nem todos os membros normais do objeto System. Diagnostics. Process. NET Framework estão disponíveis. Os métodos normais são mostrados aqui (gps é um alias para o cmdlet Get-Process, gm um alias para Get-Member e ndashm é o suficiente do parâmetro ndashmembertype para distingui-lo na linha de console do Windows PowerShell). PS C: gt gps gm método - m TypeName: System. Diagnostics. Process Nome MemberType Definição 8212- 821282128212- 821282128212- BeginErrorReadLine Método System. Void BeginErrorReadLine () BeginOutputReadLine Método System. Void BeginOutputReadLine () CancelErrorRead Método System. Void CancelErrorRead () CancelOutputRead Método System. Void CancelOutputRead () Fechar Método System. Void Fechar () CloseMainWindow Método bool CloseMainWindow () CreateObjRef Método System. Runtime. Remoting. ObjRef CreateObjRef (type requestedType) Dispose Método System. Void Dispose () Equals Método bool Equals (System. obj Object) Método GetHashCode int GetHashCode () GetLifetimeService Método System. Object GetLifetimeService () Método GetType tipo GetType () InitializeLifetimeService Método System. Object InitializeLifetimeService () Mate Método System. Void Kill () Actualizar Método System. Void Refresh () método Start bool start () ToString Método ToString string () WaitForExit Método WaitForExit bool (milissegundos int), Métodos System. Void WaitForExit () WaitForInputIdle Método bool WaitForInputIdle (milissegundos int), bool WaitForInputIdle () do objeto desserializado são mostrados aqui onde eu uso o mesmo Comando que eu usei anteriormente. PS C: gt procObj gm método - m TypeName: Deserialized. System. Diagnostics. Process Nome MemberType Definição 8212- 821282128212- 821282128212- ToString cadeia Método ToString (), ToString string (string formato, System. IFormatProvider formatProvider) PS C: GT Junte-se Me amanhã para um post convidado pelo Microsoft MVP e Scripting Honorário Guy Don Jones em novas resoluções yearrsquos. Convido-vos a seguir-me no Twitter e Facebook. Se você tiver alguma dúvida, envie um e-mail para mim em scriptermicrosoft. Ou postar suas perguntas no Fórum Oficial Scripting Guys. Te vejo amanhã. Até lá, paz. Retornando um código de saída de um script PowerShell Terça-feira, 13 de julho de 2010 Retornando um código de saída de um script do PowerShell parece fácil, mas não é tão óbvio. Neste post do blog vou mostrar uma abordagem que funciona para os scripts PowerShell que podem ser chamados de PowerShell e scripts em lote, onde o comando a ser executado pode ser especificado em uma seqüência de caracteres, executar em seu próprio contexto e sempre retornar o erro correto código. Abaixo está um tipo de transcrição dos passos que eu levei para chegar a uma abordagem que funciona para mim. É uma transcrição dos passos que eu tomei, para as conclusões apenas saltar para o final. Em muitos posts do blog, você pode ler sobre como chamar um script do PowerShell que você chama de um script em lotes e como retornar um código de erro. Isso se resume ao seguinte: Write-Host quotExiting com código 12345quot exit 12345 PowerShell - NonInteractive - NoProfile - Command quotamp quot echo De Cmd. exe: Exit. ps1 saiu com código de saída errorlevel Executando c: temptestexit. cmd resulta na seguinte saída : Saindo com o código 12345 De Cmd. exe: Exit. ps1 saiu com o código de saída 12345 Mas agora queremos chamá-lo de outro script do PowerShell, executando o PowerShell: PowerShell - NonInteractive - NoProfile - Commando c: tempexit. ps1 Write-Host quotFrom PowerShell: Exit. ps1 saiu com código de saída LastExitCodequot Executando c: temptestexit. ps1 resulta na saída a seguir: Saindo com código 12345 De PowerShell: Exit. ps1 saiu com código de saída 1 Isso não é o que esperávamos O que acontece Se o script simplesmente retornar O código de saída é 0, caso contrário, o código de saída é 1, mesmo se você sair com um código de saída Mas o que se chamamos o script diretamente, em vez de através do comando PowerShell Nós mudamos exit. ps1 para: Write-Host quotGlobal valor da variável: globalvariablequot Write-host quotExiting com código de 12345quot saída 12345 E nós mudar testexit. ps1 para: pt: GLOBALVarißvel quotMy mundial valuequot variável amp c: tempexit. ps1 Write-host quotFrom PowerShell: Exit. ps1 saiu com o código de saída LastExitCodequot Execução c: temptestexit. Ps1 resulta na seguinte saída: Valor da variável global: Meu valor da variável global Saindo com o código 12345 Do PowerShell: Exit. ps1 saiu com código de saída 12345 Isso é o que queríamos Mas agora estamos executando o script exit. ps1 no contexto do Testexit. ps1, a variável global globalvariable definida ainda é conhecida. Não é isso que queremos. Queremos executá-lo é isolamento. Vamos mudar c: temptestexit. ps1 para: pt: GLOBALVarißvel quotMy valuequot variável global PowerShell - NonInteractive - NoProfile - Command c: tempexit. ps1 Write-Host quotFrom PowerShell: Exit. ps1 saiu com o código de saída LastExitCodequot Execução c: resultados temptestexit. ps1 em A saída a seguir: Valor da variável global: Saindo com o código 12345 Do PowerShell: Exit. ps1 saiu com o código de saída 1 Não estamos executando exit. ps1 no contexto de testexit. ps1, o que é bom. Mas como podemos alcançar o Santo Graal: Escreva um script do PowerShell que pode ser executado a partir de scripts de lote e do PowerShell Que retorna um código de erro específico Que pode ser especificado como uma string Pode ser executado tanto no contexto de um script PowerShell de chamada E Uma chamada para o PowerShell) no seu próprio espaço de execução Eu mudo c: temptestexit. ps1 para: global: globalvariable quotMy variável global valuequot PowerShell - NonInteractive - NoProfile - Command160 Write-Host quotFrom PowerShell: Exit. ps1 saiu com código de saída LastExitCodequot This is the Mesma abordagem como quando nós o chamamos do script de lote. Executando c: temptestexit. ps1 resulta na saída a seguir: Valor da variável global: Saindo com o código 12345 Do PowerShell: Exit. ps1 saiu com o código de saída 12345 Isso é fechar. Mas queremos ser capazes de especificar o comando a ser executado como string, por exemplo: comando quotc: tempexit. ps1 - param1 x - param2 yquot Eu mudo c: tempexit. ps1 para: (suporte para variáveis, teste se em seu próprio contexto) param (param1, param2) Write-host quotparam1param1 param2param2quot Write-host quotGlobal valor da variável: globalvariablequot Write-host quotExiting com código de 12345quot saída 12345 Se mudarmos c: temptestexit. ps1 para: pt: GLOBALVarißvel quotMy comando quotc mundial valuequot variável: Tempexit. ps1 - param1 x - param2 yquot Invoke-Expression - Commando comando Write-Host quotDe PowerShell: Exit. ps1 saiu com código de saída LastExitCodequot Temos um bom código de saída, mas ainda estamos executando no contexto de testexit. ps1. Se usarmos o mesmo truque como em chamar de um script de lote, que funcionou antes de Nós mudamos c: temptestexit. ps1 para: global: globalvariable quotMy variável global valuequot comando quotc: tempexit. ps1 - param1 x - param2 yquot PowerShell - NonInteractive - NoProfile - Command Write-Host quotDe PowerShell: Exit. ps1 saiu com código de saída LastExitCodequot Executando c: temptestexit. ps1 resulta na seguinte saída: De PowerShell: Exit. ps1 saiu com código de saída 0 Ok, vamos usar o Invoke-Expression novamente. Vamos mudar c: temptestexit. ps1 para: pt: GLOBALVarißvel quotMy comando quotc mundial valuequot variável: tempexit. ps1 - param1 x - param2 yquot PowerShell - NonInteractive - NoProfile - Command Write-Host quotFrom PowerShell: Exit. ps1 saiu com o código de saída LastExitCodequot Executando C: temptestexit. ps1 resulta na seguinte saída: Não é possível ligar argumento ao parâmetro Comando porque é nulo. Devemos voltar a executar o comando como uma seqüência de caracteres, portanto, não entre parênteses (em um bloco de script). Voltar para o início Voltar para o início Submeter comentários Mais Informações Vamos mudar c: temptestexit. ps1 para: pt: GLOBALVarißvel quotMy comando quotc mundial valuequot variável: tempexit. ps1 - param1 x - param2 yquot PowerShell - NonInteractive - NoProfile - Command comando Write-Host quotFrom PowerShell: Exit. ps1 saiu com o código de saída LastExitCodequot Executando c: temptestexit. ps1 resulta na seguinte saída: param1x param2y Valor da variável global: Saindo com o código 12345 Do PowerShell: Exit. ps1 saiu com o código de saída 1 Ok, podemos executar o texto do comando especificado como se fosse um comando do PowerShell. Mas ainda temos o problema de código de saída, apenas 0 ou 1 é retornado. Vamos tentar algo completamente diferente. Vamos mudar c: tempexit. ps1 para: param (param1, param2) função ExitWithCode 160.160.160 param 160.160.160 (160160160160160160160 exitcode 160.160.160) 160.160.160 host. SetShouldExit (exitcode) 160.160.160 saída Write-Host quotparam1param1 param2param2quot Write-Host valor da variável quotGlobal: globalvariablequot Write-Host QuotExiting com código 12345quot ExitWithCode - exitcode 12345 Write-Host quotAfter exitquot O que fazemos é especificar para o host o código de saída que gostaríamos de usar e, em seguida, basta sair, tudo na função de utilidade mais simples. Executando c: temptestexit. ps1 resulta na seguinte saída: param1x param2y Valor da variável global: Saindo com o código 12345 Do PowerShell: Exit. ps1 saiu com o código de saída 12345 Ok, isso cumpre todos os nossos sonhos do Santo Graal Mas não poderíamos fazer a chamada do script em lotes também mais simples Mudança c: temptestexit. cmd a: PowerShell - NonInteractive - NoProfile - Command quotc: tempexit. ps1 - param1 x - param2 yquot eco de Cmd. exe: Exit. ps1 saiu com o código de saída errorlevel Execução c: temptestexit. cmd Resulta na seguinte saída: param1x param2y Valor da variável global: Saindo com código 12345 De Cmd. exe: Exit. ps1 saiu com código de saída 12345 Isso é ainda mais simples Agora podemos chamar o código do PowerShell, sem a saída LastExitCode truque E agora o Conclusões após essa longa longa história, que levou muito tempo para descobrir (e para ler para você): Não use exit para retornar um valor do código do PowerShell, mas use a seguinte função: function ExitWithCode 160160160 param 160160160 (160160160160160160160 exitcode 160160160 ) 160160160 host. SetShouldExit (exitcode) roteiro Chamada 160160160 saída do lote usando: PowerShell - NonInteractive - NoProfile - Command quotc: tempexit. ps1 - param1 x - param2 yquot echo errorlevelCall do PowerShell com: (Comando especificado na cadeia, executar no contexto próprio ) Comando quotc: tempexit. ps1 - param1 x - param2 yquot PowerShell - NonInteractive - NoProfile - Como comando LastExitCode contém o código de saída Chamada do PowerShell com: (comando direto, executar no próprio contexto) PowerShell - NonInteractive - NoProfile - Command LastExitCode contém o Exit codeCall de Powershell com: (Comando especificado em string, invocar no contexto do chamador) comando quotc: tempexit. ps1 - param1 x - param2 yquot Invoke-Expression - Commando comando LastExitCode contém a saída codeCall do PowerShell com: (comando direto, execute em Contexto chamador) amp c: tempexit. ps1 - param1 x - param2 y LastExitCode contém o código de saída 9 Comentários Nice post, mas por que haven39t você usou o switch de arquivo em vez do switch de comando Se você só quer executar um script e está interessado em Seu código de saída parece-me muito mais simples: powershell - noprofile - noninteractive - file C: tempexit. ps1 Com - file você can39t especificar quaisquer argumentos. Na verdade, você pode especificar argumentos, pelo menos na v2 PowerShell. Powershell - File myscript. ps1 - param1 value1 - param2 value2. Etc isso está funcionando bem para mim. Obrigado por compartilhar. Na função ExitWithCode, don39t você quer quotexit exitcodequot Isso não funciona para mim (XP / PS1), em lote executar o meu código de saída é 0, não importa o que eu definir no script ps. Em outras palavras, o que é valor de exitcode para colocar em host. SetShouldExit (exitcode), errorlevel retornar 0 ou o que eu especificar para o comando exit, assim quotexit 358quot funciona e dar-me código de saída 358. Amazing post. Pergunta rápida: Não deve ser uma das explicações na Conclusão de como chamá-lo incluir o 39amp39 personagem para - Command altamente descritivo post, eu amei que pouco. Haverá uma parte 2 Hey lá eu apenas desejo oferecer-lhe um polegar grande acima para sua informação que excelente você começou para a direita aqui neste borne. Eu estarei retornando a seu local para mais logo. Os comentários foram desativados para este conteúdo.

No comments:

Post a Comment