Start-Process gibt tlw. keinen ReturnCode aus (PowerShell)
Hallo @ All!
Irgendwie stehe ich wieder mal am Schlauch und hoffe wieder auf tatkräftige Starthilfe!
Hier mein Problem:
Ich rufe eine Exe auf via: $RC = (Start-Process -FilePath <Irgend eine exe> /s -PassTru)
-Wait gebe ich absichtlich nicht an ich will nämlich, dass in der PS-Console sowas wie ein Fortschrittsbalken läuft. das mache ich so:
do {
write-host "*" -NoNewLine
if ($RC.ExitCode -gt -1) { Break}
Start-Sleep 1
} until ($RC.ExitCode -gt -1)
write-host ("ExitCode: + $RC.ExitCode)
Jetzt kommt es vor, dass entweder die Schleife nicht beendet wird obwohl der ExitCode sicher 0 oder höher ist, oder der ExitCode ist $null.
mit -Wait bekomme ich natürlich immer eine ExitCode, da habe ich aber auch keine Fortschrittsbalken. Den will ich aber unbedingt haben, weil einige EXEn und MSIs ziemlich groß sind und entsprechend lange brauchen.
Hat jemand ne Idee wie ich da eine saubere und vor allem sichere Lösung zustande bekomme??
Danke!
Mayho
Irgendwie stehe ich wieder mal am Schlauch und hoffe wieder auf tatkräftige Starthilfe!
Hier mein Problem:
Ich rufe eine Exe auf via: $RC = (Start-Process -FilePath <Irgend eine exe> /s -PassTru)
-Wait gebe ich absichtlich nicht an ich will nämlich, dass in der PS-Console sowas wie ein Fortschrittsbalken läuft. das mache ich so:
do {
write-host "*" -NoNewLine
if ($RC.ExitCode -gt -1) { Break}
Start-Sleep 1
} until ($RC.ExitCode -gt -1)
write-host ("ExitCode: + $RC.ExitCode)
Jetzt kommt es vor, dass entweder die Schleife nicht beendet wird obwohl der ExitCode sicher 0 oder höher ist, oder der ExitCode ist $null.
mit -Wait bekomme ich natürlich immer eine ExitCode, da habe ich aber auch keine Fortschrittsbalken. Den will ich aber unbedingt haben, weil einige EXEn und MSIs ziemlich groß sind und entsprechend lange brauchen.
Hat jemand ne Idee wie ich da eine saubere und vor allem sichere Lösung zustande bekomme??
Danke!
Mayho
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 227812
Url: https://administrator.de/contentid/227812
Ausgedruckt am: 27.11.2024 um 16:11 Uhr
4 Kommentare
Neuester Kommentar
Hallo Mayho,
Schau dir mal dieses Mulithreading-Beispiel an:
Powershell GUI bleibt während einer While schleife hängen...
Würde den Prozess in einen parallelen Thread verlagern worin du dann mit -wait auf den Prozess wartest und dann den Exit-Code an den Hauptthread übergibst. Gerade bei MSI-Dateien ist es so das die Shell auf das Ende von msiexec warten sollte, denn sonst kommt es zu dem Phänomen das ein falscher Exit-Code ausgegeben wird (das liegt daran das msiexec ursprünglich nicht als Konsolenanwendung ausgelegt worden ist)
Was auch eine Möglichkeit wäre ist das CMDlet Start-Job mit dem sich so was realisieren ließe. Melde mich dazu nochmal...
Bis dahin ...
Grüße Uwe
Schau dir mal dieses Mulithreading-Beispiel an:
Powershell GUI bleibt während einer While schleife hängen...
Würde den Prozess in einen parallelen Thread verlagern worin du dann mit -wait auf den Prozess wartest und dann den Exit-Code an den Hauptthread übergibst. Gerade bei MSI-Dateien ist es so das die Shell auf das Ende von msiexec warten sollte, denn sonst kommt es zu dem Phänomen das ein falscher Exit-Code ausgegeben wird (das liegt daran das msiexec ursprünglich nicht als Konsolenanwendung ausgelegt worden ist)
Was auch eine Möglichkeit wäre ist das CMDlet Start-Job mit dem sich so was realisieren ließe. Melde mich dazu nochmal...
Bis dahin ...
Grüße Uwe
Noch ein Beispiel wie du es machen kannst:
Grüße Uwe
# Hashtable beinhaltet später die Informationen aus dem parallelen Thread
$rc = @{}
# Neuen Thread erstellen
$myjob = [Powershell]::Create().AddScript({
param($result)
# hier dein Aufruf deiner MSI-Datei
$r = start-process "msiexec /i install.msi /qn" -wait -PassThru
$result.ExitCode = $r.ExitCode
}).AddArgument($rc)
# Thread starten
$myjob.BeginInvoke()| out-null
# Warte auf das Ende des Threads
while($myjob.InvocationStateInfo.State -eq "Running"){
write-host "*" -NoNewLine
sleep(1)
}
# Gebe ExitCode aus
echo "`r`nExit-Code: $($rc.ExitCode)"
Ich habe vor lange Zeit gelesen, dass PowerShell mit ExitCode Eigenschaft von Process ein Problem hat.
Die Erklärung war viel zu Kompliziert, und ich habe vergessen.
Ich habe das Problem so korrigiert:
function Get-ProcessExitCode {
[CmdletBinding()]
param(
[parameter(Mandatory=$true, ValueFromPipeline=$true)]
[System.Diagnostics.Process]$Process)
Begin {
$private:type = [System.Diagnostics.Process]
$private:prop = $private:type.GetProperty("ExitCode")
}
Process {
return $private:prop.GetValue($Process)
}
}
$RC.WaitForExit() # Wait for process to finish!
$exitcode = Get-ProcessExitCode $RC # Get the ExitCode
Die Erklärung war viel zu Kompliziert, und ich habe vergessen.
Ich habe das Problem so korrigiert:
function Get-ProcessExitCode {
[CmdletBinding()]
param(
[parameter(Mandatory=$true, ValueFromPipeline=$true)]
[System.Diagnostics.Process]$Process)
Begin {
$private:type = [System.Diagnostics.Process]
$private:prop = $private:type.GetProperty("ExitCode")
}
Process {
return $private:prop.GetValue($Process)
}
}
$RC.WaitForExit() # Wait for process to finish!
$exitcode = Get-ProcessExitCode $RC # Get the ExitCode