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.
- 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. :)
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]
Related
I want to make a GUI Windows application that can run console applications. When this happens, the console window should not be shown. Instead its content should be shown in a visual component (memo/richedit). This component should show exactly the same content which would appear in the console window, even the color of the text and its background should be displayed. So this visual component should work exactly as a console window. I know that the standard output can be captured but many console applications do not use it. Is it possible to capture the output of a console application this way? Are there Windows API calls that can handle this?
I use Delphi XE2 but C# code would also be helpful.
You have to run the console mode program with stdout redirection to a pipe that your Delphi program will create. Your Delphi program can read the pipe to get the console mode program output and do whatever it needs to. By the way, this works not only with Delphi but also with any language able to create pipe and run program with I/O redirection.
If you need Delphi code to do that, have a look at this reference.
There is a ready-to-run component on GitHub: DosCommand
The Demo shows two ways how to do what you describe.
I am not sure if it works for older versions like XE2, but at least you can give it a try.
Traditionally you would call CreateProcess with stdin/stdout set to pipes you created. This should work for most programs but not for anything that uses a ncurses style "GUI" and you also lose the color information. An example can be found on MSDN.
Windows 10 (1809?) added support for pseudoconsoles. This is used by the new Terminal application and is your best bet for full console compatibility.
The last alternative is to inject into the child process and hook WriteFile, ReadFile and all the console functions but this is ugly and error-prone.
Here's the situation: Our C# WPF application needs to parse the output that a 3rd-party console application writes to a file. Starting the process and parsing the file after WaitForExit() would be easy enough, but unfortunately the app was written such that after 20 lines of output, it stops output and waits for the user to hit return. Yes, even though it writes its output to a file, it will still pause and wait for the user to hit return before writing the next 20 lines. The 3rd-party app is completely closed source and there's no hope of recompiling it to disable this behavior. It's quirky in another respect, too: Despite being a console app, it must be run within it's own directory. Given that it's a win32 port of an old DOS app, I guess I shouldn't be surprised.
I'm aware of the usual solutions like WaitForInputIdle() or hacky win32 stuff, but I can't really find anything that suits my situation. Anything that involves finding an open window and sending input via win32 isn't an option for us since the console app can't be run in a window.
So what do you think? Have I not found the right win32 hack yet? Maybe I should wrap the console app in a winform and then I can use WaitForInputIdle()?
If it's a normal console app, simply set UseShellExecute to false and RedirectStandardInput to true, then use the StandardInput property to write a newline when needed.
Using files is an extremely outdated approach, at least 20 years past. Whenever you find yourself using them, you should consider modern standard input/output piping.
I've been thinking of giving the in Windows implemented cmd a fresh look and make a WinForm out of it(C# .net4.0 or later or latest mono# distribution).
Now, what I plan on doing is:
only showing the form, no console visible(even in the task bar)
telling the cmd what to do by virtually typing into it
catching the consoles output and using the form to make the user interact
I thought of some kind of "return" thing, like a dll would do, but I have not used consoles and forms together in a single project, so there's my question:
How do I not show a console window but write commands into it's line and receive the output with a WinForms application?
Thanks in advance.
--EDIT
I should maybe add that my main problem is typing catching the consoles output and also typing into it while it's not visible and thus not focusable.
You may well run into difficulties other than simply suppressing the appearance of a console window. But as far as that particular requirement goes, it's not hard.
You'll use the System.Diagnostics.Process class to start the process. Before starting the process, you'll need to see ProcessStartInfo.CreateNoWindow property to true. Note that you also need to set ProcessStartInfo.UseShellExecute to false, otherwise the CreateNoWindow property is ignored.
As for the broader problem: it seems likely that you'll need to start the console process using "cmd.exe /k" to instantiate a new command-line interpreter process without it exiting before you're done with it. Then you'll also need to use the redirection features in the Process class to read from stdout and stderr, and to write to stdin.
Is there a way to monitor processes starting in the system before they start?
Example:
On programs like ZoneAlarm or Antivirus programs, when you run a program it asks you if you allow running this program or not before it runs...
There's a few ways to do this. If you only need to track process creation coming from a specific program (or a few programs), the EasyHook/Detours method mentioned here will work pretty well, but you effectively need to install a hook on CreateProcess into each program, so it's not a great solution if you want to track all process creation in the system.
There's a specific API for this in NT-based Windows variants (NT/2000/XP/Vista) called PsSetCreateProcessNotifyRoutine(). Unfortunately, you can only call this function from ring0, so it needs to be done in a driver. There's a handy explanation (and code) in this CodeProject article: http://www.codeproject.com/KB/threads/procmon.aspx.
AFAIK, this is just a notification, and does not by itself allow you to tell the system whether the process should be created or not. However, if you needed to do this, you could pause the process (e.g. by attaching to it as a debugger) while your code decides whether to kill it or not.
You should check out the easyhook-continuing-detours project, which is a .NET port of the Microsoft Detours project. It will allow you to hook unmanaged APIs (such as CreateProcess). Check out code examples for a simple FileMon-like program here.
You can find out when processes start via using a real-time ETW consumer - however, to be able to take some action that could possibly cancel the process from starting, you'll have to do something shady / undocumented, like hooking CreateProcess, or using a kernel filter driver to block reads to the EXE.
Just use process creation notifications .
It's included in Windows.
You don't need to hook anything.
Is there a way to monitor processes starting in the system before they start?
Example:
On programs like ZoneAlarm or Antivirus programs, when you run a program it asks you if you allow running this program or not before it runs...
There's a few ways to do this. If you only need to track process creation coming from a specific program (or a few programs), the EasyHook/Detours method mentioned here will work pretty well, but you effectively need to install a hook on CreateProcess into each program, so it's not a great solution if you want to track all process creation in the system.
There's a specific API for this in NT-based Windows variants (NT/2000/XP/Vista) called PsSetCreateProcessNotifyRoutine(). Unfortunately, you can only call this function from ring0, so it needs to be done in a driver. There's a handy explanation (and code) in this CodeProject article: http://www.codeproject.com/KB/threads/procmon.aspx.
AFAIK, this is just a notification, and does not by itself allow you to tell the system whether the process should be created or not. However, if you needed to do this, you could pause the process (e.g. by attaching to it as a debugger) while your code decides whether to kill it or not.
You should check out the easyhook-continuing-detours project, which is a .NET port of the Microsoft Detours project. It will allow you to hook unmanaged APIs (such as CreateProcess). Check out code examples for a simple FileMon-like program here.
You can find out when processes start via using a real-time ETW consumer - however, to be able to take some action that could possibly cancel the process from starting, you'll have to do something shady / undocumented, like hooking CreateProcess, or using a kernel filter driver to block reads to the EXE.
Just use process creation notifications .
It's included in Windows.
You don't need to hook anything.