tags:

views:

335

answers:

2

I am not quite sure about the difference among the console (in "windows console application"), cmd.exe, a shell.

  • I know cmd.exe is a stand-alone process when running, is cmd.exe == shell ? So shell is just a process?
  • is console == cmd.exe?
  • MSDN says ProcessStartInfo.UseShellExecute==True means use the shell when starting the process, does it mean that the process is started just the same as i run a cmd.exe and run the program from that command prompt? What's the point of doing this? Does the process started this way has its own console?

Thanks in advance.

+3  A: 

As far as I know:
Shell: A interface for the operating system and ultimately, the kernel. this includes explorer.exe and cmd.exe
Console: You instantiate the Win32 Console. That is the window that outputs your Console.WriteLine
cmd.exe : the windows command line interpreter. it instantiates the Win32 Console

More reading:
http://en.wikipedia.org/wiki/Win32_console [The win32 console, the console that you use if you don't require a graphical user interface]

ItzWarty
smwikipedia
In reality, Explorer.exe is a file manager, and it is analogous to Dolphin. However, i've seen it called a shell many times. When you set useshellexecute to false, the application will not create a win32 console. Instead, you can actually steal the output of the application's [So basically, the application won't open a win32 console. Instead, all output/input like Console.WriteLine will be sent to you]... Otherwise, if useshellexecute is set to true, it creates a win32 console and outputs there. and gets input there.
ItzWarty
Explorer.exe is a multipurpose application, yes it's a file manager, but it's also a shell, as in the root application that runs when a user logs in. The windows desktop is actually explorer.exe, and provides all the shell functions (launching other applications mostly).
Mystere Man
It is, in fact if you kill it it removes the start menu and stuff. However, windows dialogs will still function as you can still create windows
ItzWarty
+5  A: 
- MSDN says ProcessStartInfo.UseShellExecute==True means use the shell when starting the process, does it mean that the process is started just the same as i run a cmd.exe and run the program from that command prompt? What's the point of doing this? Does the process started this way has its own console?

Actually it works like this:

  • if UseShellExecute is false, the application will be started using the CreateProcess API; this API lets you specify a lot of startup options, among which there is the possibility to redirect stdin/stdout/stderr, but will only start executables. If you try to launch a file (e.g. a word document) with CreateProcess, it will fail, because word documents aren't executable files.
  • if UseShellExecute is true, the process will be started using the ShellExecuteEx API; this function is the same function that Windows Explorer ("the shell", at least in Microsoft terminology) uses when you double click on a file in a folder; its main advantage is that it "knows" how to start documents (opening them with the associated programs), it's aware of shell folders, ... because it uses a lot of the shell facilities. However it has some major drawbacks: it's quite heavyweight compared to the bare CreateProcess (because it has to perform a lot of extra work), it fails to open even executables if something is wrong with file associations/shell extensions/... and it can't redirect stdin/stdout/stderr. Not that theoretically it would be impossible: after all ShellExecuteEx internally calls CreateProcess; the problem is that it doesn't expose this feature.

So, the two methods of creating a process are really quite different; the Process class does a great job at flattening them, but a feature that absolutely cannot be reproduced with the ShellExecuteEx function is the IO streams redirection, since it's not made available by the ShellExecuteEx function and it can be enabled only at process start via CreateProcess.

The use of the console by the started program is another question. The console is allocated/reused inside CreateProcess (actually IIRC it has to do with the windows PE loader, that checks the required subsystem in the PE header); the rules for console creation/reusing are specified here.

If the started application is a GUI application, no consoles are created at all; on the other hand, if a console application is started it reuses its parent process' console, unless it specified in the CreateProcess call the CREATE_NEW_CONSOLE flag. The default is not to specify this flag, but I'm not sure of what does ShellExecuteEx do with console applications, and I don't have a Windows box at hand to check. I'll leave this as an exercise to the reader. :P


Additional answers

Hi, Matteo, another question. If i create a new process as a detached process which don't have a console attached. Where is the process's stdout now? Where does's the process's output go? Is the process's stdout differnt from console's ouput?

It's not clear to me what you mean. When you start a new process with CreateProcess/ShellExecuteEx the console is allocated as needed, i.e. if the exe is a console executable (as specified in the PE header), Windows provides it a console (that is a new one or the parent's one depending on the rules I specified above); if the exe is a GUI application no console is allocated for it.

IIRC, for GUI applications stdout/stdin/stderr are just bit buckets, i.e. they point to nothing useful and all IO to them is discarded; by the way, nothing stops a GUI application from allocating a console and redirecting its own std* streams to it.

Keep in mind that the console, the Windows std streams and the CRT std streams are three separate things. The console is just an interface, that for console applications is conveniently bound by default to the Windows std streams.

The Windows std streams are the ones that are redirected when you specify stdin/stdout/stderr redirection in CreateProcess; you can get handles to them with the GetStdHandle function, and redirect them with the SetStdHandle.

The CRT stdin/stdout/stderr, finally, are yet another abstraction, built by the C runtime library; they are bound by default to the Windows std streams.

All this normally work seamlessly and you don't even have to bother about the difference between the Windows std streams and the CRT streams; however, when you start to think about streams redirection this difference becomes important.

If process's stdout stream is differnt from console's output, And Shell make the binding of these 2 streams for us. Would the ouput of a process be copied from process.stdout to console.output? is that efficient?

The shell isn't involved in this process, is the kernel that does the plumbing, following the instructions used in the CreateProcess (or subsequently modified from inside the new process with other APIs). For your performance concerns, with a layered structure like this it's the only way to go; and moreover, the copying part (if it's really a copy, I suspect that the whole thing is just a matter of passing pointers around) is the fastest part of the process, the real bottleneck is the console window painting/scrolling/etc. In facts, if you want to run a console application letting it produce data at full speed, you usually redirect its standard output to a file or through a pipe.

Many many thanks. Matteo Italia. You are a good problem sovler. :D

Thank you. :)

Matteo Italia
Many many thanks. Matteo Italia. You are a good problem sovler. :D
smwikipedia
Hi, Matteo, another question. If i create a new process as a detached process which don't have a console attached. Where is the process's stdout now? Where does's the process's output go? Is the process's stdout differnt from console's ouput?
smwikipedia
If process's stdout stream is differnt from console's output, And Shell make the binding of these 2 streams for us. Would the ouput of a process be copied from process.stdout to console.output? is that efficient?
smwikipedia
Answers appended to the original answer.
Matteo Italia