UWP Console apps
In my last two blogposts, I’ve already shown some really cool features coming in the Windows Redstone 4 update. Also new in the RS4 update is the ability to create UWP Console apps! As there currently is no project template available in Visual Studio, there are a couple of things that need to be set-up manually. If, in the future, the project template becomes available, this blogpost will still give you some background information about the ‘magic’ this template will do.
Update (07/06): Microsoft has released an update to the Console UWP App project templates on the Visual Studio marketplace. Find out more here.
Create new project and throw away everything…
… well, not everything 🙂
To get started, create a new UWP project in Visual Studio.
Then, select the appropriate UWP versions (at the moment of writing this is “Windows 10 Insider Preview Build 17120”). Once that is done, you can start removing some stuff! As we are building a Console app, we don’t need App.xaml(.cs) and MainPage.xaml(.cs), just delete these 4 files. Next, we need to add a new file: Program.cs. As a result, your project will look something like this:
Add DISABLE_XAML_GENERATED_MAIN Compilation Symbol
In the Properties window of our UWP app, we need to add DISABLE_XAML_GENERATED_MAIN to the Conditional Compilation Symbols. This prevents the build system from generating the default Main method.But how will our UWP start without a Main method? Simple, we are going to write our own!
Start building
In this newly created Program class, we are going to add a Main method:
namespace UwpConsole { class Program { static void Main(string[] args) { } } }
Looks a lot like your classic Windows Console applications, doesn’t it? 🙂 Well, just like in your classic console applications, this is going to be our entry point. We now only need to hint Windows where it can find this Main method. For this, we need to open the Package.appxmanifest file.
To begin with, we need to add two extra namespaces: xmlns:uap5=”http://schemas.microsoft.com/appx/manifest/uap/windows10/5″ and xmlns:desktop4=”http://schemas.microsoft.com/appx/manifest/desktop/windows10/4″
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5" xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4" IgnorableNamespaces="uap mp desktop4 uap5">
Now, we can start using these namespaces in our appxmanifest. Next, we need to tell that this app will run in the console (and can run in multiple instances). This can be done by adding the following attributes to the Application element: desktop4:Subsystem=”console” desktop4:SupportsMultipleInstances=”true” . Also we need point the EntryPoint attribute to the class, containing our Main method. So in the end, the entire Application tag will look something like this:
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="UwpConsole.Program" desktop4:Subsystem="console" desktop4:SupportsMultipleInstances="true">
Now, we can already run the application from Visual Studio! If everything is correct, a Console window will pop-up. Probably, the window will also immediately close, just like with classic Console applications. So let’s put some code in our Main method:
static void Main(string[] args) { Console.WriteLine("Hello UWP Console!"); Console.ReadKey(); }
Cool! Our first UWP Console app! And just like you would expect: if you add ‘Command Line Arguments’ to your Start options (right-click your project -> properties -> Debug), you’ll get them in your Main method through the args parameter!
But wait, there’s more!
Now we have an app that can be launched just like a regular UWP app, but instead of showing a UI, a console window opens up. That’s cool, but wouldn’t it be great if we could run our console app from, well…, the console itself?
In order to accomplish this, we need to add an AppExecutionAlias to the Appxmanifest file:
<Extensions> <uap5:Extension Category="windows.appExecutionAlias" Executable="UwpConsole.exe" EntryPoint="UwpConsole.Program"> <uap5:AppExecutionAlias desktop4:Subsystem="console"> <uap5:ExecutionAlias Alias="UwpConsole.exe" /> </uap5:AppExecutionAlias> </uap5:Extension> </Extensions>
The Alias that you provide in the ExecutionAlias element, is the alias that you will be able to use from the console:
FYI: If you go to Settings in Windows and select Apps, there’s this link ‘Manage app execution aliases’. If you click this link, you’ll get an overview of all apps that have an alias registered on your system:
Let’s do something cool!
Now that we got our very basic app running, let’s talk to a UWP api from it. How about triggering a toast notification from the console?
static void Main(string[] args) { string content, title; if (args.Length == 2) { title = args[0]; content = args[1]; } else { Console.Write("\nPlease enter the content for you notification: "); content = Console.ReadLine(); Console.Write("Please enter the title for your notification: "); title = Console.ReadLine(); } Console.Write("\nSending notification..."); ToastNotifier notifier = ToastNotificationManager.CreateToastNotifier(); XmlDocument toastXDoc = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText02); XmlNodeList toastNodes = toastXDoc.GetElementsByTagName("text"); toastNodes.Item(0).AppendChild(toastXDoc.CreateTextNode(title)); toastNodes.Item(1).AppendChild(toastXDoc.CreateTextNode(content)); IXmlNode toastNode = toastXDoc.SelectSingleNode("/toast"); XmlElement audioElem = toastXDoc.CreateElement("audio"); audioElem.SetAttribute("src", "ms-winsoundevent:Notification.Reminder"); ToastNotification toast = new ToastNotification(toastXDoc); notifier.Show(toast); Console.WriteLine("Notification sent!"); Console.ReadKey(); }
You can find this code on GitHub.
Another example of a UWP Console app can be found in this blogpost. In this post we use a UWP Console app that does image classification using WinML.
That’s it
Yet another cool new UWP thing coming to RS4! Curious to see what tools or other stuff you guys will be building and publishing through the store! Or maybe some awesome text-based adventure game? (I’d pay for that 😉 )
May 16, 2018 at 9:10 pm
Thanks so much for these instructions! I built a little UWP console app to update a file for myself, and it works fine as long as I build/run in the debug configuration. If I try to run it after building in the release configuration, the app wont launch. Any thoughts on why that might be the case?
May 17, 2018 at 9:33 am
Glad you like it!
Concerning your problem, you might take a look at differences between your debug and release configuration. If you can’t find it out, please provide me your Solution so I could take a look at it, if you want.
May 29, 2018 at 10:26 pm
Ezra –
Same thing here, but it works after unchecking “Compile with .NET Native tool chain” in project Properties/Build.
PieEatingNinjas –
I have a couple different questions to add: The console app comes up after the usual default Windows app window.. can that be skipped so only a console app runs?
And there is a Windows Store app activation error after the console+window are closed.. can that be oppressed? [“Compile with .NET Native tool chain” being a store requirement, why bother..?]
BTW, same behaviors with your GitHub project.
Barring those minor issues this is undoubtedly a good testing tool for libraries, OAuth2 redirect (per custom app URIs, otherwise out-of-reach for normal console apps), etc.
May 30, 2018 at 6:32 pm
Hello – Initially I got this working despite being on too old of a version of Windows 10, however that produced an extra non-console window to appear and an “..unable to activate..” error. Those problems went away as soon as I updated to 1803.
Since the issue Ezra saw (Release not working) only seems to be remedied by unchecking “Compile with .NET Native tool chain”, is it a forgone conclusion that console UWP apps cannot be sold @ the store?
June 6, 2018 at 8:06 pm
Check out my comment above about there being a template from which to build the C# UWP console apps now. Fingers crossed it fixes this issue.
June 6, 2018 at 8:05 pm
Thanks for the reply! I’ll take a look again after I follow these directions to put the app back together. Maybe the template will solve the problem.
https://blogs.windows.com/buildingapps/2018/06/06/c-console-uwp-applications/#lx6114BhGKvLgCmi.97
June 6, 2018 at 7:33 pm
Nice walk-through. You might clarify the “we need to add an AppExecutionAlias to the Appxmanifest file” with some context about where it needs to be added. I had to go look at the github project to figure that part out.
January 26, 2019 at 7:41 pm
Exactly what is was looking for. Suggestion, post full sample code on github
January 31, 2019 at 3:55 pm
Hi John,
The code is already available on GitHub (https://github.com/PieEatingNinjas/UwpConsoleApp/tree/master). Did you miss this or do you have a remark about the source code itself?
January 17, 2024 at 3:25 pm
Hi, still useful this information. Thank you