Processo de espera da waitforexit


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!

O que é o processo de início do PowerShell? Como executar um arquivo de uma linha de comando no Windows.
O PowerShell é uma ferramenta incrível; você pode até estender seus poderes com o Azure PowerShell para controlar a funcionalidade robusta do Azure, permitindo que você use cmdlets para provisionar VMs, criar serviços em nuvem e executar vários outros processos complexos.
No Stackify, somos grandes fãs do Azure, mas isso não quer dizer que é a melhor escolha para todos (confira nossa comparação entre o Azure e o AWS aqui se você estiver no cerca). Independentemente de você pretender estender para o Azure ou apenas usar a antiga variedade do Windows, você precisará entender o básico, e é por isso que escrevemos essa postagem. Leia mais para mais.
Definição do Processo de Início do PowerShell.
O cmdlet PowerShell Start-Process abre um arquivo executável, como um arquivo de script. Se não for um arquivo executável; inicia o programa associado ao arquivo.
Como funciona.
O PowerShell é uma linguagem de script que permite aos usuários automatizar e gerenciar sistemas Windows e Windows Server. Pode ser executado em shell baseado em texto ou scripts salvos. Start-Process é um comando de cmdlet - a. k.a.
Se você pensar no PowerShell como um carro, o Start-Process seria a chave de ignição que liga o carro. A tarefa ou tarefas especificadas em uma linha seria como dar uma volta no seu veículo.
O Start-Process executa o arquivo ou arquivos especificados no computador local (que é um recurso que ajuda a proteger contra hacks remotos). O cmdlet permite que os usuários especifiquem parâmetros que acionam opções.
Como acessar a interface de linha de comando (CLI)
Clique no Windows PowerScreen na tela Iniciar ou na barra de tarefas. Execute o PowerShell como administrador: clique com o botão direito do mouse em Windows PowerShell na tela Iniciar ou na barra de tarefas. Clique em Executar como administrador.
Como usá-lo.
Ao usar a CLI do PowerShell, a sintaxe básica de um cmdlet do Power-Start é:
Para iniciar um programa chamado notepad na unidade C, use:
Parâmetros de início de processo.
Os parâmetros adicionam mais poder ao cmdlet. Por exemplo, isso iniciará o Bloco de Notas, maximizará a janela e a manterá até que o usuário termine com o Bloco de Notas:
Os parâmetros que podem ser usados ​​incluem:
-ArgumentList - Parâmetros ou valores de parâmetros a serem usados. - Credencial - Especifique a conta do usuário para executar o processo. A credencial padrão é o usuário atual. - FilePath (obrigatório) - Especifique o caminho do arquivo e o nome do arquivo do programa ou documento a ser executado. - LoadUserProfile - Carrega o perfil de usuário do Windows para o usuário atual. - NoNewWindow - Inicia o processo na janela atual do console, caso contrário, uma nova janela é criada por padrão. - PassThru - Retorna um objeto de processo para cada processo sem gerar nenhuma saída. - RedirectStandardError - Envia mensagens de erro para um arquivo especificado pelo caminho e nome do arquivo em vez de exibir erro no console por padrão. - RedirectStandardInput - Entrada de leitura de um arquivo especificado pelo caminho e pelo nome do arquivo. - RedirectStandardOutput - Envia a saída para um arquivo especificado pelo caminho e pelo nome do arquivo. - UseNewEnvironment - Use novas variáveis ​​de ambiente em vez das variáveis ​​de ambiente padrão para o computador e o usuário. - Verb - Executa uma ação que está disponível para a extensão de nome de arquivo do arquivo especificado. - Wait - Aguarde o processo ser concluído antes de aceitar mais entradas. - WindowStyle - Altere o estado da janela para o novo processo. Opções disponíveis: Normal Hidden Minimized Maximized - WorkingDirectory - Especifique a localização do arquivo que será executado. O padrão é o diretório atual. CommonParameters - Parâmetros que podem ser usados ​​por qualquer cmdlet.

PowerShell do processo Waitforexit
Eu tenho o seguinte código no meu aplicativo:
System. Diagnostics. Process proc = new System. Diagnostics. Process ();
Uma vez que eu chamo isso através de outro aplicativo, o processo está pendente.
Então eu dei um tempo de 5 segundos e agora funciona bem. Mas preciso encontrar uma maneira melhor de corrigir esse problema, pois esse valor de tempo limite pode depender dos recursos do sistema e da quantidade de aplicativo de entrada que precisa ser processada.
Então, minha pergunta é se estamos criando um processo usando System. Diagnostics, o SO cria um thread separado e o torna como thread principal ou thread de interface do usuário?
Ou está criando um thread CLR que é o mesmo que System. Threading. Thread?
Se usarmos o pool de segmentos para criar um segmento de trabalho, essa seria uma opção melhor?

PowerShell do processo Waitforexit
Eu estou tentando iniciar um processo e pegue o StandardOutput e StandardError usando EventHandlers e BeginOutputReadLine. Eu posso iniciar o processo, mas recebo.
Exceção chamando & quot; BeginOutputReadLine & quot; com & quot; 0 & quot; argumento (s): & quot; Não é possível misturar operação síncrona e assíncrona no fluxo do processo. & quot;
Aqui está a minha função de lançamento:
Estou violando o modelo de segmentação Powershell? Obrigado!
Eu estou tentando iniciar um processo e pegue o StandardOutput e StandardError usando EventHandlers e BeginOutputReadLine. Eu posso iniciar o processo, mas recebo.
Exceção chamando & quot; BeginOutputReadLine & quot; com & quot; 0 & quot; argumento (s): & quot; Não é possível misturar operação síncrona e assíncrona no fluxo do processo. & quot;
A mensagem de erro está dizendo o que você está fazendo errado.
Você não pode atribuir funções a um processo síncrono. As funções não são delegadas, portanto, não funcionarão. Você precisa usar um modelo de evento ou usar a variação de asynch.
Use isso como um modelo:
Marcado como Resposta Oliver Lipkau Moderator quarta-feira, 12 de outubro de 2011 2:32.
Todas as respostas.
Eu acredito que você tenha alguns erros no seu código. Eu sou a pessoa mais humilde que você já conheceu.
Eu estou tentando iniciar um processo e pegue o StandardOutput e StandardError usando EventHandlers e BeginOutputReadLine. Eu posso iniciar o processo, mas recebo.
Exceção chamando & quot; BeginOutputReadLine & quot; com & quot; 0 & quot; argumento (s): & quot; Não é possível misturar operação síncrona e assíncrona no fluxo do processo. & quot;
A mensagem de erro está dizendo o que você está fazendo errado.
Você não pode atribuir funções a um processo síncrono. As funções não são delegadas, portanto, não funcionarão. Você precisa usar um modelo de evento ou usar a variação de asynch.
Use isso como um modelo:
Marcado como Resposta Oliver Lipkau Moderator 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 o. WaitForExit - olhando para ele agora, vejo por que isso não acontece.
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 o. WaitForExit - olhando para ele agora, vejo por que isso não acontece.
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 delegado de evento. Mas então este é o PowerShell, não é VB.
Você pode começar aqui e ver se o evento que você está procurando pode ser "viciado"
help Register-ObjectEvent - full.
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:
& quot; Uma condição de deadlock pode resultar se o processo pai chama p. WaitForExit antes de p. StandardOutput. ReadToEnd e o processo filho grava texto suficiente para preencher o fluxo redirecionado. O processo pai aguardaria indefinidamente que o processo filho fosse encerrado. O processo filho esperaria indefinidamente que o pai lesse o fluxo StandardOutput completo. & Quot;
Eu também estou tentando a melhor resposta para fazer este trabalho no Powershell, mas todos os exemplos de código que estou executando em que usam System. Diagnostics. Process no powersehll estão replicando o deadlock nesta implementação ou não estão redirecionando stderr e stdout.
A solução que estou usando 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 formos usar saída redirecionada, não usaremos espera. Esse foi o design de CreateProcess desde o NT4.
O uso de arquivos para capturar a saída funcionará porque um fluxo é anexado e envia 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 córrego corre o contexto do sistema do pecado eu acredito e começarei sempre a possibilidade de ler. A espera está no seu thread, então você não pode fazer uma leitura manual. É um impasse como afirmado.
O uso da leitura do console é geralmente porque estamos procurando por 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 nós apenas usamos threads separe para IO e um para espera. Melhor ainda, eu usaria um semáforo como ele pode capturar dinamicamente um desligamento inesperado.
Talvez a próxima versão do PowerSHell tenha boas possibilidades de multithreading.
Esta é apenas mais uma lição de que o Powershell é uma linguagem de script, não uma linguagem de programação e, por mais poderosa que seja, existem armadilhas.
O código de exemplo da Microsoft simplesmente não é abrangente o suficiente para um hacker Powerhell perceber que eles não podem chegar lá a partir daqui. Isso é o que me pegou e acredito no OP também, porque houve uma certa expectativa de que BeginOutputReadline implementou a mágica para fazer com que funcionasse threads que teriam resolvido o problema de bloqueio. Não, então acabamos aqui.
E uma ligeira correcção ao meu código - deixei o sinalizador - wait que é necessário para o resto do código funcionar:
Esta é apenas mais uma lição de que o Powershell é uma linguagem de script, não uma linguagem de programação e, por mais poderosa que seja, existem armadilhas.
O código de exemplo da Microsoft simplesmente não é abrangente o suficiente para um hacker Powerhell perceber que eles não podem chegar lá a partir daqui. Isso é o que me pegou e acredito no OP também, porque houve uma certa expectativa de que BeginOutputReadline implementou a mágica para fazer com que funcionasse threads que teriam resolvido o problema de bloqueio. Não, então acabamos aqui.
E uma ligeira correcção ao meu código - deixei o sinalizador - wait 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 de o programa ser encerrado.
O 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 de esperar para redirecionar. Você precisa esperar pelos arquivos e como uma maneira fácil de detectar a 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 é tudo demais para os administradores de scripts e, como você apontou, os deixará sem problemas.

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.

Gerenciando Processos no PowerShell.
Várias pessoas perguntaram recentemente sobre como gerenciar processos no PowerShell. Esta postagem do blog deve responder a várias dessas perguntas.
Como se poderia esperar do & # 8220; shell & # 8221; Como parte do PowerShell, você não precisa fazer nada especial para iniciar um processo. Em uma linguagem de programação como o VBScript, você precisa fazer algo bastante complexo como:
Defina objWMIService = GetObject (& # 8220; winmgmts: & # 8221; _.
Defina objStartup = objWMIService. Get (& # 8220; Win32_ProcessStartup & # 8221;)
Defina objConfig = objStartup. SpawnInstance_.
Defina objProcess = GetObject (& # 8220; winmgmts: raiz \ cimv2: Win32_Process & # 8221;)
objProcess. Create & # 8220; Notepad. exe & # 8221 ;, Null, objConfig, intProcessID.
mas em shells (PowerShell, cmd. exe, bash, etc.) você pode simplesmente iniciar um programa como o bloco de notas simplesmente digitando & # 8220; notepad & # 8221; como mostrado.
Agora você notará que, quando fizer isso, o shell retornará imediatamente e solicitará o próximo comando. Isso porque o notepad é um processo de GUI do win32 e é executado em segundo plano. Por outro lado, se você iniciar um aplicativo de console como o & # 8220; ping. exe & # 8221 ;, o PowerShell esperará até que esse processo seja concluído.
Mas e se eu quiser esperar pelo processo do Win32? No cmd. exe, você faria isso com & # 8220; start / wait & # 8221; mas esse comando não está (diretamente) disponível no PowerShell. Então, o que fazemos?
O PowerShell executa diretamente executáveis. Se aguarda a saída do processo, o código de saída será deixado em $ LASTEXITCODE. Agora, se um executável do Win32 for o último comando em um pipeline e não for redirecionado, o processo será executado em segundo plano. No entanto, se você enviar sua saída para algo, o PowerShell aguardará a saída do comando.
Portanto, essa é uma espera simples (se não intuitiva) para aguardar a saída de um processo da GUI.
Como alternativa, se o processo já estiver em execução, você poderá usar Get-Process para recuperar as informações necessárias e, em seguida, executar um WaitForExit () nesse objeto.
Aqui está um exemplo um pouco mais sofisticado, onde abrimos um documento em vez de iniciar um processo. Dessa vez, encontraremos o processo pelo título da janela, e não pelo nome do executável.
Infelizmente, procurar um processo sempre significa que você pode encontrar o processo errado. Idealmente, você gostaria de obter o objeto Process diretamente. Portanto, para um gerenciamento de processos mais preciso, você terá que usar a classe System. Diagnostics. Process e iniciar os processos por conta própria. Por exemplo, você pode usar [diagnostics. process] :: Start () para aguardar um processo:
Observe o uso de & # 8220; $ pwd \ foo. txt & # 8221; para especificar o caminho completo para o arquivo. Isso ocorre porque o PowerShell mantém sua própria ideia do diretório atual. (Esta nota se aplica ao uso de qualquer API que acesse o sistema de arquivos - você precisa dar um caminho absoluto.)
Agora, estamos começando a voltar ao nível de complexidade que você encontra em uma linguagem de programação. No entanto, você também tem todo o poder dessas linguagens. Aqui está um script de exemplo & # 8220; background. ps1 & # 8221; Isso permitirá que você execute um scriptblock desanexado em uma janela separada (ou na mesma janela se você especificar o parâmetro – inconsole.
Este script permite que você faça coisas no PowerShell que você não pode fazer a partir do cmd. exe, mas pode fazer a partir do VBScript.
Finalmente, aqui estão mais duas maneiras de trabalhar com processos. Mesmo que o PowerShell não tenha um comando de início, o cmd. exe faz isso, você pode iniciar / esperar fazendo.
E, por último, mas não menos importante, o PowerShell Community Extensions inclui um cmdlet Start-Process. Você pode obter uma lista desses recursos em:
Bruce Payette [MSFT]
Windows PowerShell Tech Lead.
Top Server & # 038; Blogs de ferramentas.
Postagens recentes.
DSC Resource Kit versão de fevereiro de 2018 7 de fevereiro de 2018 Configuração do estado desejado (DSC) Planning Update & # 8211; Janeiro de 2018 26 de janeiro de 2018 PowerShell Core 6.1 Roadmap 24 de janeiro de 2018 PowerShell Core 6.0: disponível em geral (GA) e com suporte! 10 de janeiro de 2018.
Eu tenho um script master powershell chamando um subscrito. O subscrito lança um erro, mas $ LASTEXITCODE em MASTER não parece pegá-lo.
Basicamente meu processo pára no momento em que o comando throw é executado e o processo não é retornado para o MASTER.
Existe uma maneira de contornar isso?
Muito obrigado por este artigo !
Seria muito bom ver uma versão atualizada disso com todas as extensões V2 como Start-Process e as extensões Jobs.
Obrigado por todo o trabalho duro, o PowerShell está se preparando para ser uma ferramenta realmente incrível para automação de processos!
Você pode encontrar mais detalhes aqui: [link] Shay [link]
Uma breve pesquisa no google: & amp; lt; [link] & gt; onde é dada a ponta a saída do pipe para out-null. bloco de anotações.
Na verdade eu estou integrando o VB e um programa escrito em C ++. Eu sou capaz de executar este programa C ++, clicando em um botão projetado em VB. Quando clico no botão, o prgram é executado na plataforma DOS. Eu não quero essa plataforma DOS visível. Mas o processo C ++ deve continuar rodando em segundo plano, invisível.
Se eu passar o scriptblock que contém variável, o código não parece funcionar. Isso ocorre porque o processo filho não herda as variáveis ​​do pai. Como posso superar isso?
Bruce, eu tenho andado por aí com runspaces para obter processamento em background de scriptblocks (em ps1.soapyfrog / 2007/01/22 / running-pipelines-in-the-background /)
Será que provavelmente veremos isso se tornando mais amigável nos próximos lançamentos?
Eu percebo que os runspaces estão realmente disponíveis para aplicativos host, mas eles parecem úteis.
Seu comentário no & quot; site de conexão do PowerShell & quot; é notado.
& # 8220; $ np = bloco de notas do processo get & # 8221; é * extemely * acertar ou errar se você usar muito o bloco de notas. Você poderia classificar os processos por data de início, criados por você, etc., em um esforço para mitigar os erros, mas sim & # 8211; deveríamos ter fornecido uma maneira de obter o processo mais recente criado em um runspace. Em vez de ter uma única variável $ LASTPROCESS, eu estava pensando que uma matriz de $ process ao longo das linhas de $ error seria legal. O processo criado mais recentemente seria mantido em $ process [0].
& gt; como o PowerShell é um shell, o controle de processos / tarefas não deve ser um cidadão de primeira classe.
Isso parece óbvio se não tivesse implementado um cmdlet New-Process / Start-Process, mas foi cortado do projeto em um ponto. Na triagem do que ocorreu na V1, nada além do gerenciamento básico de processos obteve uma classificação relativamente baixa, pois o PowerShell permite que você tenha acesso ao [Diagnostics. Process]. Isso significa que, embora possa ser complexo, você pode fazer praticamente qualquer coisa. Enviar é escolher como Jeffrey diz.
Poste uma solicitação no site de conexão do PowerShell para que outras pessoas possam modificá-lo. Esta é uma fonte de dados importante no processo de tiragem para o que vai para a próxima versão. Se um número suficiente de pessoas pedir, então ele vai para a lista curta do V. Next.
E, respondendo a um comentário anterior:
& gt; Qual é o poder de equivalência dos processos de inicialização em máquinas remotas, ele ainda usa o WMI?
As operações remotas no 1.0 exigem que você use o WMI, APIs remotos ou outros mecanismos de remoting existentes. O PowerShell 1.0 não possui recursos remotos explícitos. Suporte para remoting é um Pri 0 para o próximo lançamento.

Comments

Popular Posts