Powershell: Start-Process -NoNewWindow broken in core edition

Created on 27 Jul 2016  路  19Comments  路  Source: PowerShell/PowerShell

Steps to reproduce

Start-Process -NoNewWindow powershell

Expected behavior

Run process in a new window

Actual behavior

Run process in the same window, but UX is broken

PS /Users/vors> Start-Process -NoNewWindow powershell                                                                                        
PS /Users/vors> 14;1Rl                                                                                                                       
14pyright (C) 2016 Microsoft Corporation. All rights reserved.
1Rl : The term '1Rl' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, 
or if a path was included, verify that the path is correct and try again.
At line:1 char:4
+ 14;1Rl
+    ~~~
    + CategoryInfo          : ObjectNotFound: (1Rl:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

PS /Users/vors>                 ^Dlssaad  

Environment data

Repros on OS X, Linux and Windows

> $PSVersionTable

Name                           Value                                                                                                        
----                           -----                                                                                                        
PSVersion                      5.1.10032.0                                                                                                  
PSEdition                      PowerShellCore                                                                                               
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}                                                                                      
BuildVersion                   3.0.0.0                                                                                                      
GitCommitId                    v6.0.0-alpha.7                                                                                               
CLRVersion                                                                                                                                  
WSManStackVersion              3.0                                                                                                          
PSRemotingProtocolVersion      2.3                                                                                                          
SerializationVersion           1.1.0.1  
Area-Cmdlets Committee-Reviewed Issue-Bug OS-Linux OS-Windows OS-macOS Up-for-Grabs WG-Interactive-Console

All 19 comments

@vors Expected behavior is not quite correct. According to Get-Help Start-Process:

-NoNewWindow [<SwitchParameter>]
    Start the new process in the current console window. By default Windows PowerShell opens a new window.

it should start in the current console window.

However, UX being broken is still true, - it seems that both parent and child powershell.exe processes are competing for user input. This is my attempt to type $PSVersionTable:

PS C:\Users\Giorgi.Chakhidze> Start-Process -NoNewWindow powershell.exe
PS C:\Users\Giorgi.Chakhidze> $SesoTal
Copyright (C) 2016 Microsoft Corporation. All rights reserved.

PS C:\Users\Giorgi.Chakhidze>
$ PVrinbe

Yeah, can confirm this is still broken.

Can confirm it is still reproducible.

Definitely broken, but It is worth noting that Start-Process -NoNewWindow powershell doesn't make much sense, given that it amounts to running an _interactive_ shell _asynchronously_ in the current terminal (which results in _two_ shells competing for input, as @0xfeeddeadbeef's experience suggests).

Adding -Wait - Start-Process -Wait -NoNewWindow powershell - works properly, but there's no good reason to use it, given that just invoking powershell directly is not only simpler (it implicitly runs synchronously in the current terminal), but is also properly integrated with the current session's input/output streams, unlike a Start-Process call.

-NoNewWindow is really only useful in very limited circumstances:

  • for console applications (GUI applications open their own (non-console) window anyway)
  • that produce no output / whose output is redirected via -RedirectStandardOutput / -RedirectStandardError

It is a poor substitute for using a _job_ to launch a console application in the background, which gives you much better control.

Unless I'm missing other use cases for -NoNewWindow, it may be a candidate for deprecation.

True, counting the number of negatives is hard :D
If I recall correctly, the reason I opened the issue is the there is mismatch in behavior and on core powershell it's implicit NoNewWindow.

@vors: It may be time to decide the fate / behavior of Start-Process on Unix platforms: please see #4521.

How about making NoNewWindow a no-op on unix?

Any update on this? @SteveL-MSFT

@PowerShell/powershell-committee reviewed this, when using start-process -nonewwindow pwsh, it should behave the same as just typing pwsh. This should just be a bug. Same if using bash instead of pwsh

@SteveL-MSFT, can you please clarify?

Given that Start-Process is _asynchronous_ by default, why should Start-Process -NoNewWindow pwsh (_asynchronous_ -> battle for keyboard) behave the same as just pwsh (_synchronous_ -> OK, child shell)?

Are you saying that exceptions should be built into Start-Process?

@mklement0 great question. start-process -nonewwindow foo is effectively synchronous as I don't believe there is a single use case where the intent is to have a process started async that fights for the console. So the specific behavior is only if -NoNewWindow is used to behave as though you executed foo without using start-process.

@SteveL-MSFT:

start-process -nonewwindow foo can be useful as a lightweight _asynchronous_ way to call _launch-and-forget-it_ processes that are known (designed to) _neither solicit stdin input nor to produce terminal output_, which, on Linux, includes GUI apps whose CLIs are blocking, such as gedit.

Of course, on Unix you can just omit -NoNewWindow in that case, given that it's not supported and that running in the same terminal is the invariable default.

On a general note, remember that verb Start implies _asynchronous_ operation (even though Start-Sleep didn't get the memo).

I think it would make sense to have -NoNewWindow be a separate parameter set to -Wait. In every case I've seen for -NoNewWindow it doesn't make any sense, as you say, to have it async, so it should just behave as -NoNewWindow -Wait does currently without the extra parameter, and have -Wait simply be an option when you're _not_ using -NoNewWindow. 馃槃

There is _no_ reason to involve Start-Process at all if you want to run a _console/terminal-based_ application _synchronously_: not only is _direct_ invocation simpler, only the latter guarantees that the invoked program's output streams are connected to PowerShell's.

Start-Process is asynchronous by default; that's what the standard verb in its name implies, and I don't think there should be any exceptions, _especially not for use cases that make no sense to begin with_.

-NoNewWindow in effect _is_ a no-op on Unix-like platforms, and it makes sense to document it as such.

Yes, that means that someone can shoot themselves in the foot with something like Start-Process [-NoNewWindow] bash on Unix, but to me that's still preferable to special-casing behavior.
Sensible use cases for Start-Process on Unix are very limited compared to Windows; I've tried to summarize them here - integration into the docs is pending.

@mklement0 I agree that Start implies async and also agree that -NoNewWindow doesn't make sense on Unix-like platforms. However, it doesn't make sense to continue to allow users to get into this situation. However, I don't see this as a priority to fix as I don't believe it affects a large number of users and I expect they'll learn quickly not to use it again after the first time.

@SteveL-MSFT:

I expect they'll learn quickly not to use it again after the first time.

Yes, which is why I think the problem can be dealt with by simply providing proper guidance in the Start-Process help topic (_update_: see https://github.com/MicrosoftDocs/PowerShell-Docs/issues/3013):

  • By stating in the Description section that -NoNewWindow is _invariably implied_ on Unix-like platforms.

  • By stating in the description of parameter -NoNewWindow:

    • that (possibly implied) -NoNewWindow is only relevant to _console/terminal_-based applications and generally only makes sense in very limited circumstances (to put it differently: _typically_, there's _no_ need to use Start-Process to invoke console/terminal-based programs):

      • Launch-it-and-forget-it _console/terminal_-based commands known not to produce output / expect interactive input (if the target program is _not_ console/terminal-based, there's no reason to use -NoNewWindow to begin with),
    • _Console/terminal_-based commands that require _running with a pristine environment_ with -UseNewEnvironment; if such commands happen to produce output / require interactive input, then -Wait must used, too. (On Windows, if the process with a pristine environment should run in a new window anyway, there's obviously no need for -NoNewWindow.)

    • that not also including -Wait for console/terminal-based application will cause them to send output asynchronously / compete for interactive input with the calling session.

when using -NoNewWindow I get this error: This command cannot be run due to the error: %1 is not a valid Win32 application.

I've come across issues with this today wondering why my Start-Process with -NoNewWindow parameter was seeming to hang until I pressed enter...

As @mklement0 stated above, I agree that the help topic should be updated. After spending a bit of time with several searches and articles trying to figure out the problem, I finally came across this issue... Noting that one should use "-Wait", or altering the behavior of -NoNewWindow to implicitly wait, would seem to be very helpful. Had it been in the contents of the Start-Process help, I would've known immediately...

For my use case, I've been using Start-Process for running PSExec with various parameters, as I cycle through pushing updates to many servers. But for simplicy, the behavior I'm seeing can be reproduced on all PowerShell versions 5-7.1 I've tried so far like this:

Start-Process -FilePath IPConfig -NoNewWindow

The output will be shown, with the cursor just sitting at the bottom flashing, and only bring back the prompt after I hit enter or up arrow... As long as I append "-Wait" it behaves as desired...

Thanks, @BouwenMA.

Note the pending issue requesting updating of the docs (it's been open since December 2018): https://github.com/MicrosoftDocs/PowerShell-Docs/issues/3013 - if you're up for it, you could try to submit a PR yourself.

Also - in case ipconfig.exe wasn't just a random example - remember that there's generally no good reason to use Start-Process with _console_ applications such as ipconfig.exe (or psexec), as explained above and as also covered in the linked issue.

Was this page helpful?
0 / 5 - 0 ratings