1

I have looked here

https://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.createnowindow(v=vs.110).aspx

And I understand that

A) Not every program respects it CreateNoWindow request and

B) It requires UseShellExecute=False (default is true).

C) It is meant to indicate whether a window is created. (it won't ever hide the parent window). It's speaking of whether a window is created for the child process. (msdn says 'new window')

D) CreateNoWindow defaults to false.

I am running this from cmd, though clicking play in visual studio illustrates the same behaviour.

I set CreateNoWindow to false so i'd have thought it'd create a new window for the child process.

But it does not.

task manager shows the second instance of cmd.exe but there's still the one window as you can see. Below is the paste from one window. It has loaded the child cmd.exe in the parent window (the one cmd window)

If I set CreateNoWindow to true or false, then it seems to make no difference.

So i'm clearly not getting the example at that msdn link to work.

C:\crp>type aaa.csc
using System.Diagnostics;

class blah{
   public static void Main(string[] args) {
          Process p = new Process();
          ProcessStartInfo psi = new ProcessStartInfo();
          psi.UseShellExecute=false; 
          psi.FileName="cmd.exe";
          psi.CreateNoWindow=false;
          p.StartInfo=psi;
          p.Start();
   }
}
C:\crp>csc aaa.csc
Microsoft (R) Visual C# Compiler version 4.0.30319.34209
for Microsoft (R) .NET Framework 4.5
Copyright (C) Microsoft Corporation. All rights reserved.


C:\crp>aaa.exe

C:\crp>Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\crp>

UPDATE

It seems it does work. If you open a cmd prompt and run the exe, then in one case it starts cmd.exe within the parent. In the other case it starts a cmd.exe without any window. The behaviour within visual studio seems odd though, see my comment to ephraim's answer. In this question while within visual studio, i'd only tried it with the project set to being a console application, and there a cmd prompt window will always at least flick up. Behaviour is much simpler for a non console application e.g. a winforms application.

barlop
  • 12,887
  • 8
  • 80
  • 109

4 Answers4

2

I have finally found the answer by correctly understanding of CreateNoWindow. CreateNoWindow is about creating parent window which will cover the target application main window.

CreateNoWindow = false;

=> This will cause Process to create a parent window to hold the target app window, not about creating app window

WindowStyle = ProcessWindowStyle.Hidden;

=> This will hide the parent window created by Process, not the app window style

        using (Process process = new Process())
        {
            process.StartInfo.FileName = @"notepad";
            process.StartInfo.CreateNoWindow = false;
            process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            process.Start();
        }
0

Try this out using Visual Studio and define the pull file path for the cmd.exe

public static void Main(string[] args) {
    try 
    {
      ProcessStartInfo psi = new ProcessStartInfo();
      psi.FileName = "C:\\Windows\\System32\\cmd.exe"; // full path
      psi.CreateNoWindow = true; 
      psi.UseShellExecute = false;
      Process childProcess = Process.Start(psi); // child process
      // This code assumes the process you are starting will terminate itself. 
      // Given that is is started without a window so you cannot terminate it 
      // on the desktop, it must terminate itself or you can do it programmatically
      // from this application using the Kill method.
    }
    catch(Exception ex)
    {
        Console.WriteLine(e.Message);
    }
}
jegtugado
  • 5,081
  • 1
  • 12
  • 35
  • this seems to make a difference when done from visual studio, but then not from cmd.. which seems strange/ In visual studio in one settof of CreateNoWindow it keeps the cmd window open while it runs the child process. In the other case it closes it. I still am not seeing how that relates to the meaning behind CreateNoWindow – barlop Apr 25 '16 at 00:42
  • also, it appears to make no difference whether you use the full path or not, and whether you use proc.Start() or Process.Start(psi). I've posted an update to my question, and i've posted an answer. I'll upvote you since your answer helped. – barlop Apr 25 '16 at 01:48
0

I set UseShellExecute=True; ....and it seems to work.

Odd, without that line, you have to type exit twice, once to 'close' the child cmd.exe (which doesn't really close the window) and once to close the parent cmd.exe.

Steve Wellens
  • 20,506
  • 2
  • 28
  • 69
  • When you say it works, what do you call works. And when you have that line. Does CreateNoWindow then make any difference? I think you'll find that with UseShellExecute, then CreateNoWindow is ignored.. as the msdn link says. And thus it won't 'make it work'. – barlop Apr 25 '16 at 00:45
  • Without that UseShellExecute true line, i.e. with it false, it doesn't seem to create a new cmd window, regardless of CreateNoWindow(even with CreateNoWindow set to false), and that's the issue, . But anyhow, It is normal to have to type exit twice in a situation of cmd executed within the same cmd window. Try opening a cmd window then typing `cmd` `cmd` you'll see it opens cmd within cmd, if you hit the up arrow you won't see a command history because it is a new instance, and you have to type exit multiple times to exit the original cmd window. – barlop Apr 25 '16 at 00:49
  • 1
    "When you say it works, what do you call works." It created a second cmd.exe window...as expected. Someone made a bad decision when they named a property `CreateNoWindow`. It causes icky double negatives. `CreateNoWindow = false` would be better as `CreateWindow = true` – Steve Wellens Apr 25 '16 at 01:01
  • And as asked, When you have that line, does CreateNoWindow make any difference? – barlop Apr 25 '16 at 01:11
  • @barlop I don't know, I didn't try it. If you really want to know, I suppose _you_ could try it. – Steve Wellens Apr 25 '16 at 18:12
  • Why would you suggest that making a second cmd window be what u expect from CreateNoWindow? On a question of whether "a second cmd window" is created or not,The words Create No Window should cause u2 expect it 2 not create a second cmd window. And furthermore, you are making the claim that u got CreateNoWindow working.That shud mean that u got it operating right for true and operating right for false.If you're not sure about that,u haven't tested it, u concede that maybe with ur line, CreateNoWindow being true or false makes no difference, so u shouldn't write that u got CreateNoWindow working – barlop Apr 25 '16 at 23:30
0

It makes most sense to first try from a cmd.exe

then from there understand the behaviour when running from visual studio

The word new in CreateNoNewWindow, is a bit misleading. It's more like it creates no window and even uses no window.

If you have CreateNoNewWindow=false (the default), then it will run that child cmd in the parent window. (that may seem strange but if you compare it to what happens when CreateNoNewWindow=true then it's not so strange). When you run the program you'll see it says the cmd banner with Copyright e.t.c. that's from the child cmd running in the parent window.

If you have CreateNoNewWindow=true and you run your program then it will output nothing. Task manager will still show the second cmd.exe that is because it is running the child cmd.exe but not in any cmd window at all.

Now for the behaviour within visual studio.

With Visual studio console applications when you click play, visual studio will pop up its cmd window which disappears once the program has completed, but any spawned processes would live on.

With visual studio, If you have CreateNoNewWindow set to true (i.e. use no window at all), then it will pop up its cmd window, spawn the second cmd in no window, so it's invisible, then the parent cmd window will close and the spawned child cmd.exe will continue to show in task manager but will have no window. So task manager will show one cmd.exe, and you'll see no window.

As a test before testing the paragraph below, you can create a cmd window, sdfsdfds so you have something in command history accessible with up arrow so you can see whether you're in the parenet command or not. Then start a child process. type cmd<ENTER>. Now kill the parent. The child is still there.

With visual studio, if you have CreateNoNewWindow set to false(i.e. use the parent window), (this, as we have seen, is possible even after a parent process has been killed, if the child was created and using that window, before the parent was killed) then click play, then visual studio will flick up its cmd window as it does, and it will spawn a child cmd.exe process and task manager only shows one cmd.exe process but in a window, and the play button shows as active again, so the program must have completed execution, and the parent process was completed. So visual studio closed the parent cmd.exe but the child is still there still using the parent's window as it was prior to the parent cmd.exe being completed.

That's for when a visual studio project is set to console application, where a console will always at least flick up.

But for a project that isn't created as a console application e.g. for a winforms application, the console can be set to hide, and no console would flick up or need to be run at all even for the main program.

Note here- UseShellExecute and CreateNoWindow are being set to their non default values. UseShellExecute is by default true, and we set it to false because when UseShellExecute is true then CreateNoWindow ignores the value of itself(CreateNoWindow), and a new window is created(even if CreateNoWindow is set to true). CreateNoWindow is by default false, and we set it to true. If you are going to use CreateNoWindow, then the only non superfluous and working use case would be UseShellExecute=false and CreateNoWindow=true. (If UseShellExecute=true(default) then you should use process window style hidden.. ) Also bear in mind these things work for cmd.exe but fail for some other things like calc.exe

ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "cmd.exe";
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
Process.Start(psi);
barlop
  • 12,887
  • 8
  • 80
  • 109