73

When I start a new process, what difference does it make if I use the

WindowStyle = Hidden

or the

CreateNoWindow = true

property of the ProcessStartInfo class?

Edward Brey
  • 40,302
  • 20
  • 199
  • 253
Gabor
  • 1,656
  • 1
  • 16
  • 28

3 Answers3

89

As Hans said, WindowStyle is a recommendation passed to the process, the application can choose to ignore it.

CreateNoWindow controls how the console works for the child process, but it doesn't work alone.

CreateNoWindow works in conjunction with UseShellExecute as follows:

To run the process without any window:

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

To run the child process in its own window (new console)

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

To run the child process in the parent's console window

ProcessStartInfo info = new ProcessStartInfo(fileName, arg); 
info.UseShellExecute = false; // causes consoles to share window 
Process processChild = Process.Start(info); 
Edward Brey
  • 40,302
  • 20
  • 199
  • 253
Liz
  • 8,780
  • 2
  • 36
  • 40
  • 20
    One thing worth noting here that I learned the hard way: if you create a Process and then modify its StartInfo, you will get a different behavior than if you were to create a ProcessStartInfo and then use Process.Start(). Specifically, the former doesn't appear to respect CreateNoWindow. – Ari Roth May 24 '11 at 22:04
  • 2
    @AriRoth can you give a code example? You have to create a process before you can modify its StartInfo. One would always be saying process1.StartInfo = something. So you have to create the process first, and then the instance of ProcessStartInfo that you assign to process1.StartInfo it's impossible to do anything else. – barlop Apr 24 '16 at 23:50
  • @AriRoth and even if you do `Process process = Process.Start(psi);` instead of `process.Start()` i'm not convinced there is any difference of behaviour and you're still setting the StartInfo before you create the process. – barlop Apr 25 '16 at 01:14
  • how to create a new window and don't use shellexecute, I use that combo, but the window doesn't show up. – james Sep 01 '18 at 17:06
  • I think that even the fourth possibility, UseShellExecute = true and CreateNoWindow = true, is worth discussing. I think that it's useful when the parent is a visible command line application, to ensure that the child will not get its own window. At the same this supports lookup of the executable using %PATH%, execution of batch files, and similar. – Jirka Hanika Oct 10 '18 at 16:53
  • @james - This isn't doable in pure .NET, which is one of the reasons why the UseShellExecute option exists. But you can call AllocConsole through P/Invoke to achieve that. – Jirka Hanika Oct 10 '18 at 16:54
23

CreateNoWindow only applies to console mode apps, it won't create the console window.

WindowStyle only applies to native Windows GUI apps. It is a hint passed to the WinMain() entry point of such a program. Fourth argument, nCmdShow, telling it how to show its main window. This is the same hint that appears as the "Run" setting in a desktop shortcut. Note that "hidden" is not an option there, few properly designed Windows program honor that request. Since that snookers the user, he can't get the program activated anymore and can only kill it with Task Manager.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
16

Using Reflector, it looks like WindowStyle is used if UseShellExecute is set, otherwise it uses CreateNoWindow.

In MSDN's example, you can see how they set it:

// Using CreateNoWindow requires UseShellExecute to be false
myProcess.StartInfo.UseShellExecute = false;
// You can start any process, HelloWorld is a do-nothing example.
myProcess.StartInfo.FileName = "C:\\HelloWorld.exe";
myProcess.StartInfo.CreateNoWindow = true;
myProcess.Start();

In the other example, its just below because UseShellExecute is defaulted to true

// UseShellExecute defaults to true, so use the WindowStyle
ProcessStartInfo startInfo = new ProcessStartInfo("IExplore.exe");
startInfo.WindowStyle = ProcessWindowStyle.Minimized;
SwDevMan81
  • 48,814
  • 22
  • 151
  • 184
  • 1
    I agree, that agrees with my test too. Has msdn got it backwards? https://msdn.microsoft.com/en-us/library/system.diagnostics.processwindowstyle(v=vs.110).aspx they say "To use ProcessWindowStyle.Hidden, the ProcessStartInfo.UseShellExecute property must be false." <-- I believe msdn have it backwards – barlop Apr 25 '16 at 06:31