Freigeben über


How to start a console app in a new window, the parent's window, or no window

The ProcessStartInfo.CreateNoWindow property says "Gets or sets a value indicating whether to start the process in a new window." and later "true to start the process without creating a new window to contain it; otherwise, false. The default is false
But that's misleading and wrong because it's meaning changes depending on what another property (UseShellExecute) is. 

This caused me quite a bit of grief. So in the interests of helping you avoid my pain, here's what I found: (I originally started typing the feedback via MSDN Wiki; but it got long enough that I figure I may as well put it on my blog too.)

1) To run the child process without any window,

use the CreateNoWindow property and set UseShellExecute.

ProcessStartInfo info = new ProcessStartInfo(fileName, arg);
info.CreateNoWindow = true;
info.UseShellExecute = false;
Process processChild = Process.Start(info);
 

UseShellExecute=false means that Process.Start basically becomes a direct call to kernel32!CreateProcess. Practically, this means that now you just need to figure out how various ProcessStartInfo properties map to kernel32!CreateProcess flags. Presumably ProcessStartInfo defaults most flags to 0. The CreateNoWindow property translates to a CREATE_NO_WINDOW flag being passed to kernel32!CreateProcess, which means the console app runs without a window at all.  The default is to share console windows and you need to pass the CREATE_NEW_CONSOLE flag to give the child a new console.

2) To run the child process in it's own window (a new console window separate from the parent):

UseShellExecute=true, which is the default value.
ProcessStartInfo info = new ProcessStartInfo(fileName, arg);
Process processChild = Process.Start(info); // separate window

3) To run the child process in the parent's console window:

UseShellExecute=false.
ProcessStartInfo info = new ProcessStartInfo(fileName, arg);
info.UseShellExecute = false; // causes consoles to share window
Process processChild = Process.Start(info);
 

Or in nice table summary:

UseShellExecute CreateNoWindow Child console process runs in MSDN is
false true no window correct
true (default) false (default) a new window wrong
false false (default) an existing window (its parents') correct

 

Some design lessons:
There are some design lessons here:
1. Be precise in definitions when documenting your properties.  There's a significant difference between "a new window", "an existing window", and "no window".
2. Don't have a property's meaning completely change when some other unrelated property is set.

 

See also: Conventions for passing arguments to a process

Comments

  • Anonymous
    September 28, 2006
    If you want to create a new thread in your process in C#, you can use Thread.Start. But things are a...

  • Anonymous
    September 28, 2006
    Sounds like a job for an enumeration . . .

  • Anonymous
    October 05, 2006
    If you want to create a new thread in your process in C#, you can use Thread.Start . But things are a

  • Anonymous
    December 04, 2006
    thanks man! I spent a lot of time figuring out WHY my process was always starting in a new window whatever option I specify for CreateNoWindow.... thanks!

  • Anonymous
    November 07, 2018
    One thing to know about ShellExecute is, in/out streams are not supported with ShellEx true. So the wrong case in red cannot be used to have a window and debug i/o stream related issues.