Have you ever had the need to use an application (.exe) as a command line tool when started in the console (cmd.exe) and as GUI application when started from the Explorer shell? This article explains a possible implementation for this requirement.
To be clear: I didn’t find the perfect solution; a Windows .NET application is either a console application or a Windows application. Either type can be used in the opposite mode, but both variants have some drawbacks.
This article describes the solution which I think has the least disadvantages. The solution works by defining the application as console application and show the WPF window if the application is not executed in a console. The only drawback I’ve found is that the console window is shown for some milliseconds at application start.
The other approach is to define the application as Windows application, but then you will have a lot of problems when using the application in console mode, e.g. the application is started in a second window, the output is not printed to the original console and the console does not wait until the application has executed because Windows forked out the process. This is why I prefer the first solution.
Implementation
The following steps describe how to implement such a “hybrid” application:
- Create new WPF application project
-
Add a
Program.cs
file with the following content:public static class Program { [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] static extern bool FreeConsole(); [STAThread] public static int Main(string[] args) { if (args != null && args.Length > 0) { // TODO: Add your code to run in command line mode Console.WriteLine("Hello world. "); Console.ReadLine(); return 0; } else { FreeConsole(); var app = new App(); return app.Run(); } } }
-
Add a constructor in
App.xaml.cs
and callInitializeComponent()
:public partial class App : Application { public App() { InitializeComponent(); } }
-
Open project settings
- Select “Program.Main” as application entry point
- Change the type of the project to “Console application”
Final thoughts
Even if there are some solutions, I think it is better to provide two different applications which call shared assemblies. This way you avoid all the mentioned issues and do not have to live with the drawbacks of the available workarounds.
Further reading
For more information on this topic, head to the following sources:
- MSDN Blog: How do I write a program that can be run either as a console or a GUI application?
- StackOverflow Question: C#: Is it possible to have a single application behave as Console or Windows application depending on switches?
Rico Suter
SOFTWARE ENGINEERING
EDIT
.NET C# Command Line Console Application WPF