Your problem is unrelated to the use of Start-Sleep
.
Instead, the problem is that, as of Windows 10, calc.exe
is only a stub executable for the process that is ultimately launched, and the stub process exits as soon as it has launched the real executable.
If you remove the Start-Sleep
call between the Start-Process
and the echo
calls, the stub process object contained in $startedProcesses
typically does reflect the stub executable's name - calc.exe
- in the ProcessName
column at that time, due to still being alive (albeit only shortly), but you still won't be able to track the real executable's process lifetime and exit code through that object.
The real executable's name is Calculator.exe
, whose exact path incorporates a full AppX package name (a package name, a version number, and publisher ID):
For instance, after launching calc.exe
, (Get-Process Calculator).Path
yields something like:
C:\Program Files\WindowsApps\Microsoft.WindowsCalculator_10.1908.0.0_x64__8wekyb3d8bbwe\Calculator.exe
However, you can NOT use that path to launch Calculator directly - you'll get an Access denied
error, even when running with elevation.
Calculator, as an AppX package (a UWP application typically distributed via the Microsoft Store), is most easily launched by its URL scheme:
Start-Process ms-calculator:
Note:
For an automated way to discover an AppX app's URL scheme names by package name or wildcard-based part of it - e.g., *Calculator*
- see this answer.
The less convenient alternative is to use a shell:
URL that is based on an application's AppID - see this answer.
Unfortunately, as of PowerShell (Core) 7.2 / Windows PowerShell v5.1, adding -PassThru
to invocation of an AppX-package URL with Start-Process
results in an error instead of returning an object representing the launched process - though Calculator still launches; the same applies to -Wait
:
# Launches Calculator, but doesn't return a process object
# and reports an error instead:
PS> Start-Process ms-calculator: -PassThru
Start-Process : This command cannot be run completely because the system cannot find all the information required.
...
The problem has been reported in GitHub issue #10996.
Workaround:
# Invoke the *stub executable* synchronously, so that
# the real executable has already been launched by the time
# the call returns.
Start-Process -Wait -FilePath calc.exe
# Now get the real process object, named 'Calculator'.
# The newly launched or a preexisting instance is used (see below).
$processStatus = Get-Process -Name Calculator |
Where-Object SessionId -eq (Get-Process -ID $PID).SessionId).ID
Note: Calculator only ever creates one process per user session (window station): If a process already exists, subsequent launches delegate to this process.