What exactly is a "Console"? - c#

I am trying to writing a console application. It has its original console, let's name it console A. And I want this application to do the following things via C#:
Open another console B in another thread, then get input from A and output it to B;
type a command in A, such as dir, and show the output in B;
while doing the above things (still not done yet. X_X ), I find myself lack a through understanding of what a console window is, and how it is assigned to a console application, especially the very first console when my console application starts to run. Could some one shed some light on me?
Is console window physically a memory area in the video memory? Or something else?
Could different threads within the same process have different console of its own for its own I/O?
Many thanks.
Now I am using one console application to start another console application in a new process. Thus I can have 2 consoles output at the same time.
My understanding now is that, for Windows OS, a console is a special window, and it's a system resource that OS assigned to the application without-a-UI as a necessary user interface. Windows OS handles the wiring between the system-prepared console window with our UI-less application.

In Windows terms, a Console is a textual GUI window that you see when you run "cmd.exe". It allows you to write text to, and read text from, a window without the window having any other UI chrome such as toolbars, menus, tabs, etc,..
To get started you'll want to load Visual Studio, create a new project and choose "Console Application". Change the boilerplate code that Visual Studio produces to:
using System;
using System.Text;
namespace MyConsoleApp
{
class Program
{
static void Main(string[] args)
{
Console.Write("Hello, world!");
Console.ReadKey();
}
}
}
When you run your application, a console window will open with the text "Hello, world!" and it'll stay open until you press a key. That is a console application.
Is console window physically a memory area in the video memory? Or something else?
It's not physically a memory area in video memory, it's "something else". The Wikipedia Win32 console page gives a fairly robust descrption of the ins and outs.

A console application has only one window. It does not have window management functions in order to spawn child "consoles".
You can start additional console applications, but these are separate entities.

No. It's a windows GUI subsystem. In WinAPI there are functions to work with console: http://msdn.microsoft.com/en-us/library/ms682073%28VS.85%29.aspx

A (OS) console is a process (containg one or more threads of executions, all of them sharing the same memory space), and this process has:
standard input (a stream of input bytes), what you key in
standard output (a stream of output bytes), what the program prints
standard error (a stream of output bytes), what the program prints when it's complaining about something
So if you want to create another console (from .Net) and link the input/outputs I understand you have to create a process (executing "cmd.exe" by example).
I don't know the API of .Net for process manipulation but if it's like Java you can hook up stdin, out and err so you can play with your created process from the original one.

A windows application can have one console, or no console, it can't have more than one. See the documentation for AllocConsole.
The console is basically an emulation of the 'pre-Windows' days when there would literally be a 'control console' i.e. a keyboard and screen attached to a mainframe computer.
To do what you want you could spawn another process with its own console and communicate between the two, or make a GUI application which looks like a console window.

Related

Console output in WindowsForms application

I am trying to develope a windows application to display console window as output.
If i changed output type in properties to "console Application" both the console window and form showing. But i need to show only form window first, when i click a button then only the console window need to display the output value.
Please guide me...
Thanks in advance.
Each process can have only at most one console associated with it. There are several paths you can take: either you hide the console window immediately on startup and show it later (via ShowWindow), or you leave the project as a window application, and create the console manually using AllocConsole later.
In the case you wanted multiple consoles, you can e.g. create a dummy process (cmd) and attach your process to its console, using AttachConsole. The managed way would be to use remoting or other techniques to communicate with the dummy process (with your own implementation), and print texts through that.
Use NativeMethods.AllocConsole(); to allocate a console and I/O with it.
Use NativeMethods.FreeConsole(); to close and free this console.
You wanna output the Console.WriteLines of a Windows Forms app inside the form?
In that case just use Console.SetOut(Stream) and pass in something you're wrapping so you can also output it somewhere else.
Another option is to switch all your Console.WriteLines to Trace.WriteLine and add a TraceListener somewhere that does what you want.

Using the Scrollbar interrupts the Console Application

Currently when I use the scrollbar on my c# console app, it seems to halt/interrupt the application until I "let go" of the scrollbar.
Is there a way to keep this from happening?
Here's an old post I'm just quoting from, which explains the Pause when using the scrollbar in cmd prompt :
"Technically, only displaying output is suspended while you hold the scrollbar: the console subsystem temporarily stops reading from the output buffer and displaying it. However, the process remains running, and said output buffer fills up very quickly, which makes all further write()'s "block" for as long as the buffer is full. This is what makes the process appear to pause.
(Note that there are two distinct components – the console window and the programs running inside. The "Command Prompt" is only the cmd.exe command interpreter, but the window along with scrollbars is displayed by CSRSS."
Here's the link to the post : https://superuser.com/questions/344262/windows-command-prompt-pause-during-mousedown
You will need to run your long-running code in another thread, then writing to the console when need be - see this post: Using .NET BackgroundWorker class in console app

Enabling a console application through a Windows Forms application

I'm not going to go into details why am trying to do this, instead of making the main application do the work. I think it's currently easier for me. But I'm not going to use this technique in the future.
In my case, the main form has a button that opens another form. In the second one for you can adjust the amount, pause, resume and stop the work of the console application (sound totally useless (and maybe stupid), but, like I said, I'm not going to go into details why). This means that the application must have access to all the variables and resources of the whole program and vise versa.
I know how to launch a new form trough a main form, but I don't know how to launch a console application.
EDIT:
I forgot to mention, that the console application is a part of the solution.
Your requirement is a bit vague; "the application must have access to all the variables and resources of the whole program and vise versa". 'Variables and resources' cannot be shared across processes, you will instead need interprocess communication of some form.
If your console app merely needs to communicate back to the calling forms app that a RPC has succeeded then use exit codes in the console app, see: How do I return a value from a console application to a service in .NET?
Otherwise this has been answered before: Getting the ouput from Console window into Winform application
You'll need to either create a console emulator (time consuming and difficult to get right), or fire up cmd.exe in another process and use remote procedure calls (or another inter process communication method) to communicate between the two processes
If you want to communicate between the two processes, take a look at this library here:
https://github.com/TheCodeKing/XDMessaging.Net
It allows you to send messages from one app to the other. For example, App1 sends a message "stop" on the channel "randomkey" to ConsoleApp1, ConsoleApp1 can listen on the channel "randomkey" and intercept the "stop" message and stop its current processing.
If you wanted to just open the console window, just use System.Diagnostics.Process.Start();
You can just call Main directly. Beware of doing this on the UI thread directly though!
SomeConsoleApp.Main(new string[]{"-O", "File 1.txt", "-some-parameter"});
Or if you only have an exe, you can do:
System.Diagnostics.Process.Start("someconsoleapp.exe");

Difference between console and winforms applications when running from cmd

I have a winforms application that sometimes used from the command line.
Here is the code (simplified of course):
[STAThread]
static void Main()
{
AttachConsole(ATTACH_PARENT_PROCESS);
Console.WriteLine("Hello");
/*Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());*/
}
If that was a console application the output could be:
C:\ConsoleApplication\ConsoleApplication.exe
Hello
C:\ConsoleApplication\_
In case of windows application its actually:
C:\WindowsApplication\WindowsApplication.exe
C:\WindowsApplication\Hello
_
Can anyone tell me why do we have such difference and is it possible to make my windows application to behave like console when running from cmd?
edit:
I want my windows application to behave like console when running from cmd:
C:\WindowsApplication\WindowsApplication.exe
Hello
C:\WindowsApplication\_
solution:
As a result I'm running my application as
C:\WindowsApplication\start /wait WindowsApplication.exe
Yes. The difference is that cmd.exe is aware of the kind of executable. It knows to wait for the process to terminate when it is a console mode app. It does not wait when it is a regular Windows gui app. Trusting that it will create its own window. So it displays the command prompt again, your output gets appended to that. You'll also have trouble using Console.ReadLine() btw.
You'd have to start your program with start /wait yourapp.exe to force cmd.exe to wait. Calling AllocConsole() instead is the only universal fix. Also takes care of creating the console when your app gets started from a shortcut.
AllocConsole() is fairly disorienting. Consider writing a tiny console mode app that does nothing but Process.Start + WaitForExit to start your main program. Perhaps also munging the command line arguments. Now you get the blocking behavior back. If you rename the executable to mainapp.com (to start mainapp.exe) then the difference is hidden quite well, a trick that VS uses as well (devenv.exe vs devenv.com).
There is a flag in the exe, telling if this is a console app or gui (winform in your case) app. When you start an app, Windows will detach the console from the program if it is a console app. You can use the following approach to achieve what you want:
Compile you application as gui, name it mytool.exe
Create a doskey alias mytool=start /wait c:\path\mytool.exe $*
In this way, when you start mytool.exe in explorer or shortcut, you start a normal windows application; when you type in mytool in console, you actually start it by "start /wait", which will not detach the console regard less of the flag. (However, you do need to attach to parent console in your app if you want to output/input something from the console.
You want the Windows App to block the Console thread as long as it's running, if I understand you correctly. I have no idea why you would do that, but I can give a shot at how it might work:
Change the WinForms application to a console application, that opens a form. This way it would block the console thread while displaying a window.

Execute as console application when parameter is set

a few days ago, I developed a WinForms application in C# using VC#2010 Express. After creating and saving the project, I made it a console application in the project settings, so additional to the start form, a windows command line pops up. I used the console to output debug information (simply with the Console.Write() function).
So now, my app is ready for a release. I do not want the user to see the console, for sure, but I'd like to integrate a way to show the console to interested persons. So, the best way is an argument, I think (like -console), but I dont know how to start the program as a console application only when an argument is set. I know how to handle the args[] array, for sure, but I have no idea how to show the console when there is an arg. I already tried it by simply starting the program via command line(CMD -> prog.exe), but it did not work. The program starts, but the console directly shows the current path after starting the program, as usual.
Is there any possibility for my intention?
AFAIK, there is no way to have a single binary support both console and non-console behaviour, with the choice being made on start-up. All the work-arounds I've seen use two binaries.
There's a discussion here on how Python deals with the problem (boldface mine):
The standard Python.exe that comes with Python is known as a console application (this means it has been built to interact with a Windows console, otherwise known as a DOS box or command prompt). Although you can execute your Tkinter programs using Python.exe, your program will always be associated with a Windows console. It works just fine, but has the following side effects:
If you execute Python.exe from Windows Explorer, a new empty console window is created; then the Tkinter windows are created.
If you execute a Tkinter application under Python.exe from a command prompt, the command prompt doesn't return until the Tkinter application has finished. This will be a surprise for many users, who expect that executing a GUI program returns the command prompt immediately.
To get around this problem, Python comes with a special GUI version called Pythonw.exe. This is almost identical to the standard Python.exe, except it's not a console program, so doesn't suffer the problems described previously.
You could get the command line arguments for the Winform in the forms load event and then if the argument is for the console, open the console.
private void Form1_Load(object sender, EventArgs e)
{
string[] args = Environment.GetCommandLineArgs();
foreach(string arg in args)
{
if(arg == "consoleargument")
{
// Run console
}
}
}
You can link to kernel32.dll and use the function AttachConsole.
Here's an example: http://www.csharp411.com/console-output-from-winforms-application/

Categories