3

I'm using the PowerShell syntax:

Start-Process -FilePath $file -ArgumentList $argList -NoNewWindow -Wait

The process being started is an installer, which installs a Windows service and then starts up that service, then the process stops. What's happening is that my script is hanging indefinitely, even after the process completed successfully and the process has exited (as I can see in Task Manager. When I run it from a command line, without PowerShell, it's done in under a minute). Apparently, it's still waiting because there's a child process which was spawned from the original process. How can I tell PowerShell to wait only for the initial process ($file) and not any children?

Thanks

as9876
  • 876
  • 1
  • 11
  • 32
  • 1
    You could use a while loop waiting for the Windows service to exist, instead of -Wait. Sleep until it does. – Jelphy Mar 22 '18 at 21:01

3 Answers3

3

In the end, I decided to simply do it the .NETy way, even though I had preferred a Powershelly way of doing it. Code below is copied from https://stackoverflow.com/a/8762068/1378356:

$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = $file
$pinfo.UseShellExecute = $false
$pinfo.Arguments = $argList
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$p.WaitForExit()    
Write-Host "exit code: " + $p.ExitCode

This way worked without issue.

as9876
  • 876
  • 1
  • 11
  • 32
0

I have dealt with this for years. Generally speaking if the install is pretty short and simple I will just put a wait into the script (Start-Sleep 60 or whatever). If however the install runs for a very variable amount of time then I actually catalog the msiexec processes that are running right before I start the install then loop and check every 60 seconds or so to see if all the new processes have ended. It gets even more tricky if the install is calling actual child installs. Another approach that I have used to a lesser or greater degree of success depending on the install is to again loop checking every 60 seconds or so to see if a query against the WMI Win32_Product class has an instance for the product being installed. You pretty much have to tailor the solution to the install and your environment.

EBGreen
  • 33,707
  • 11
  • 58
  • 80
0

In the past, I've done the opposite, where I wanted to wait until a certain process starts in order to continue, and I've used WMI events to do it. It's worth a shot to see if the same technique helps you:

# Start a process to track
Start-Process "Notepad.exe"

# Get WMI to track process exits
Register-WmiEvent -Query "SELECT * FROM __instancedeletionevent WITHIN 5 WHERE targetinstance isa 'win32_process'" `
                    -SourceIdentifier "WMI.ProcessDeleted" `
                    -Action {
                            if($eventArgs.NewEvent.TargetInstance.Name -eq "Notepad.exe")
                            {
                                Write-Host "Notepad exited!"

                                # Raise an event to notify completion
                                New-Event "PowerShell.ProcessDeleted" -Sender $sender -EventArguments $EventArgs.NewEvent.TargetInstance | Out-Null
                            }
                    } | Out-Null

# Wait for the event signifying that we completed the work (timeout after 10 min)
Wait-Event -SourceIdentifier "PowerShell.ProcessDeleted" -Timeout 600 | Out-Null

# Remove any events we created
Get-Event -SourceIdentifier "PowerShell.ProcessDeleted" -ErrorAction SilentlyContinue | Remove-Event

# Unregister the event monitor
Unregister-Event -Force -SourceIdentifier "WMI.ProcessDeleted"

Just replace "Notepad.exe" with the name of your installer process, and remove the call to Write-Host (or replace with something more useful). If you close Notepad within 10 minutes (adjust to suit) you should see a message, otherwise we continue anyway so the script doesn't hang indefinitely.

boxdog
  • 5,910
  • 2
  • 13
  • 17
  • Very clever! Ultimately, I decided to go with New-Object System.Diagnostics.Process, as posted. – as9876 Mar 26 '18 at 18:00