Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Suppressing The Command Window Opening When Using Start-Process

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 (e.g. .\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
like image 756
Jamie Avatar asked Jan 31 '16 12:01

Jamie


People also ask

How do I suppress output in PowerShell?

To silence direct console output and discard all output, you can temporarily disable the internal PowerShell command Out-Default . This command is used privately to write directly to the console. Read more about Out-Default if you like.

How do I run a PowerShell script without displaying Windows?

To totally remove window you can do one of two things: 1: Run in a different user's context such as admin account (won't display any windows to the logged on user). Or 2: Use a vbscript with objshell. run with a hidden window flag to launch cmd.exe /c powershel.exe -file c:\script.

How do you stop Windows PowerShell from opening?

Step 1: Use Ctrl + Shift + Esc on your keyboard to launch the Task Manager. Step 2: Proceed to the tab labeled "Startup." Step 3: Disable Windows PowerShell by right-clicking the option.


1 Answers

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.

like image 200
user4003407 Avatar answered Sep 30 '22 14:09

user4003407