I'm trying to find a way to get PowerShell not to spawn a command window when running an executable using Start-Process
.
If I call the executable directly within the script (eg .\\program.exe
) then the program runs (with its arguments) and the output is returned to the PowerShell window.
If I use Start-Process
the program spawns a command window where the program runs and returns it's output.
If I try and use the -NoNewWindow
switch of Start-Process
the script then errors out saying it can't find the exe file.
I would prefer to use Start-Process
to have access to the -Wait
switch, as the programs and configurations the script makes can take some time individually to finish, and I don't want later commands starting up.
This code runs the executable in a separate command window:
Start-Process DeploymentServer.UI.CommandLine.exe -ArgumentList "download --autoDownloadOn --autoDownloadStartTime $StartTime --autoDownloadEndTime $EndTime" -Wait
This code runs the exe within the PowerShell console:
.\DeploymentServer.UI.CommandLine.exe download --autoDownloadOn --autoDownloadStartTime $StartTime --autoDownloadEndTime $EndTime
If I add the -NoNewWindow to the Start-Process code
Start-Process DeploymentServer.UI.CommandLine.exe -ArgumentList "download --autoDownloadOn --autoDownloadStartTime $StartTime --autoDownloadEndTime $EndTime" -Wait -NoNewWindow
I get the following error:
Start-Process : This command cannot be executed due to the error: The system cannot find the file specifie At C:\Temp\SOLUS3Installv1.3.ps1:398 char:22 + Start-Process <<<< DeploymentServer.UI.CommandLine.exe -ArgumentList "download --autoDownloadStartTime $StartTime --autoDownloadEndTime $EndTime" -Wait -NoNewWindow + CategoryInfo : InvalidOperation: (:) [Start-Process], InvalidOperationException + FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.StartProcessCommand
You should prefix the executable name with the current directory when you use the -NoNewWindow
switch:
Start-Process .\DeploymentServer.UI.CommandLine.exe -ArgumentList "download --autoDownloadOn --autoDownloadStartTime $StartTime --autoDownloadEndTime $EndTime" -Wait -NoNewWindow
Background information:
The first thing Start-Process
tries to do is to resolve the value of the -FilePath
parameter by PowerShell rules. If it succeeds, it replaces the value value passed with the full path to the command. If not, it leaves the value untouched.
In the Windows API there are two ways to start a new process: CreateProcess
and ShellExecute
. ShellExecute
is the default, but if you use a cmdlet parameter that requires CreateProcess
(for example, -NoNewWindow
), then CreateProcess
will be used. The difference between them, which matters for this question, is that when looking for a command to execute, CreateProcess
uses the current process' working directory, while ShellExecute
uses the specified working directory (which Start-Process
by default passes based on the current filesystem-provider location, unless explicitly specified via -WorkingDirectory
).
PS Test:\> 1..3 |
>> ForEach-Object {
>> New-Item -Path $_ -ItemType Directory | Out-Null
>> Add-Type -TypeDefinition @"
>> static class Test {
>> static void Main(){
>> System.Console.WriteLine($_);
>> System.Console.ReadKey(true);
>> }
>> }
>> "@ -OutputAssembly $_\Test.exe
>> }
PS Test:\> [IO.Directory]::SetCurrentDirectory((Convert-Path 2))
PS Test:\> Set-Location 1
PS Test:\1> Start-Process -FilePath Test -WorkingDirectory ..\3 -Wait # Use ShellExecute. Print 3 in new windows.
PS Test:\1> Start-Process -FilePath .\Test -WorkingDirectory ..\3 -Wait # Use ShellExecute. Print 1 in new windows.
PS Test:\1> Start-Process -FilePath Test -WorkingDirectory ..\3 -Wait -NoNewWindow # Use CreateProcess.
2
PS Test:\1> Start-Process -FilePath .\Test -WorkingDirectory ..\3 -Wait -NoNewWindow # Use CreateProcess.
1
PowerShell does not update the current process' working directory when you change the current location for the FileSystem
provider, so the directories can differ.
When you type:
Start-Process DeploymentServer.UI.CommandLine.exe -Wait -NoNewWindow
Start-Process
cannot resolve DeploymentServer.UI.CommandLine.exe
by PowerShell rules, since it does not look in the current FileSystem
location by default. And it uses CreateProcess
, since you specify -NoNewWindow
switch. So, it ends up looking for DeploymentServer.UI.CommandLine.exe
in the current process' working directory, which does not contains this file and thus causes an error.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.