powershell powershell-v2.0

powershell - Obteniendo ExitCode usando Start-Process y WaitForExit en lugar de-Wait



powershell-v2.0 (5)

Al probar la sugerencia final anterior, descubrí una solución aún más simple. Todo lo que tuve que hacer fue almacenar en caché el identificador del proceso. Tan pronto como lo hice, $ process.ExitCode funcionó correctamente. Si no almacenaba en caché el identificador del proceso, $ process.ExitCode era nulo.

ejemplo:

$proc = Start-Process $msbuild -PassThru $handle = $proc.Handle # cache proc.Handle http://stackoverflow.com/a/23797762/1479211 $proc.WaitForExit(); if ($proc.ExitCode -ne 0) { Write-Warning "$_ exited with status code $($proc.ExitCode)" }

Intento ejecutar un programa desde PowerShell, esperar la salida y acceder al código de salida, pero sin mucha suerte. No quiero usar -Espere con Start-Process, ya que necesito un procesamiento para continuar en segundo plano.

Aquí hay un script de prueba simplificado:

cd "C:/Windows" # ExitCode is available when using -Wait... Write-Host "Starting Notepad with -Wait - return code will be available" $process = (Start-Process -FilePath "notepad.exe" -PassThru -Wait) Write-Host "Process finished with return code: " $process.ExitCode # ExitCode is not available when waiting separately Write-Host "Starting Notepad without -Wait - return code will NOT be available" $process = (Start-Process -FilePath "notepad.exe" -PassThru) $process.WaitForExit() Write-Host "Process exit code should be here: " $process.ExitCode

Al ejecutar este script, se iniciará el bloc de notas. Después de cerrar esto manualmente, se imprimirá el código de salida y se reiniciará sin usar -wait. No se proporciona ningún código de salida cuando esto se abandona:

Starting Notepad with -Wait - return code will be available Process finished with return code: 0 Starting Notepad without -Wait - return code will NOT be available Process exit code should be here:

Necesito poder realizar un procesamiento adicional entre el inicio del programa y esperar a que se cierre, por lo que no puedo usar -Espera. ¿Alguna idea de cómo puedo hacer esto y aún tener acceso a la propiedad .ExitCode de este proceso?


Dos cosas que podrías hacer, creo ...

  1. Crear el objeto System.Diagnostics.Process manualmente y eludir el proceso de inicio
  2. Ejecute el ejecutable en un trabajo en segundo plano (¡solo para procesos no interactivos!)

Así es como podría hacer:

$pinfo = New-Object System.Diagnostics.ProcessStartInfo $pinfo.FileName = "notepad.exe" $pinfo.RedirectStandardError = $true $pinfo.RedirectStandardOutput = $true $pinfo.UseShellExecute = $false $pinfo.Arguments = "" $p = New-Object System.Diagnostics.Process $p.StartInfo = $pinfo $p.Start() | Out-Null #Do Other Stuff Here.... $p.WaitForExit() $p.ExitCode

O

Start-Job -Name DoSomething -ScriptBlock { & ping.exe somehost Write-Output $LASTEXITCODE } #Do other stuff here Get-Job -Name DoSomething | Wait-Job | Receive-Job


Hay dos cosas para recordar aquí. Una es agregar el argumento -PassThru y dos es agregar el argumento -Espera. Debe agregar el argumento de espera debido a este defecto http://connect.microsoft.com/PowerShell/feedback/details/520554/start-process-does-not-return-exitcode-property

-PassThru [<SwitchParameter>] Returns a process object for each process that the cmdlet started. By d efault, this cmdlet does not generate any output.

Una vez hecho esto, se pasa un objeto de proceso y se puede ver la propiedad ExitCode de ese objeto. Aquí hay un ejemplo:

$process = start-process ping.exe -windowstyle Hidden -ArgumentList "-n 1 -w 127.0.0.1" -PassThru -Wait $process.ExitCode # this will print 1

Si lo ejecuta sin -PassThru o -Wait, no imprimirá nada.

La misma respuesta aquí: https://.com/a/7109778/17822


La opción ''-Esperar'' pareció bloquearme a pesar de que mi proceso había terminado.

Probé la solución de Adrian y funciona. Pero utilicé Wait-Process lugar de confiar en un efecto secundario de recuperar el identificador del proceso.

Asi que:

$proc = Start-Process $msbuild -PassThru Wait-Process -InputObject $proc if ($proc.ExitCode -ne 0) { Write-Warning "$_ exited with status code $($proc.ExitCode)" }


O intenta agregar esto ...

$code = @" [DllImport("kernel32.dll")] public static extern int GetExitCodeProcess(IntPtr hProcess, out Int32 exitcode); "@ $type = Add-Type -MemberDefinition $code -Name "Win32" -Namespace Win32 -PassThru [Int32]$exitCode = 0 $type::GetExitCodeProcess($process.Handle, [ref]$exitCode)

Al usar este código, aún puede dejar que PowerShell se encargue de administrar flujos de salida / error redirigidos, lo que no puede hacer usando System.Diagnostics.Process.Start () directamente.