Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference among "Console", "cmd.exe", "shell"?

Tags:

c#

windows

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.

like image 492
smwikipedia Avatar asked Feb 26 '10 06:02

smwikipedia


People also ask

Is cmd and shell the same?

The shell is a command-line interpreter. A command line, also known as a command prompt, is a type of interface. A terminal is a wrapper program that runs a shell and allows us to enter commands.

What is difference between cmd and Command Prompt?

The command prompt is the default command-line interpreter for Microsoft Windows and few other operating systems. CMD is usually used for carrying out different routine administration tasks and is also used to perform automation. All such tasks are performed using scripts and batch files in the command prompt.

Is cmd the Windows shell?

Windows PowerShell is the new Microsoft shell that combines the old CMD functionality with a new scripting/cmdlet instruction set with built-in system administration functionality.

Is cmd.exe a terminal?

So, cmd.exe is not a terminal emulator because it is a Windows application running on a Windows machine. There is no need to emulate anything. It is a shell, depending on your definition of what a shell is.


2 Answers

- 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. :)

like image 92
Matteo Italia Avatar answered Sep 28 '22 00:09

Matteo Italia


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]

like image 35
Warty Avatar answered Sep 28 '22 01:09

Warty