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.