-
Notifications
You must be signed in to change notification settings - Fork 1.4k
HostBuilder and Host for Windows App SDK #4358
-
@michael-hawker asked me to post this for community feedback.
I have created a HostBuilder and Host for Windows App SDK Desktop applications. The repository is at sharpninja/WindowsAppSdkHost and includes the complete WindowsAppSdkHost and WindowsAppSdkHostBuilder implementations which are based on the Microsoft.Extensions.Hosting.HostBuilder and Microsoft.Extensions.Hosting.Internal.Host implementations by Microsoft. The repository contains a complete Desktop application that references and uses both the builder and host.
What does it do?
Allows hosting a Windows App SDK Application in an IHost that manages the lifecycle of the hosted Application.
Usage
(Convert existing project or the default template's output)
- Add
<DefineConstants>DISABLE_XAML_GENERATED_MAIN</DefineConstants>in the mainPropertyGroupof your applications project file. - Add reference to
CommunityToolkit.Extensions.Hosting.WindowsAppSdk - Add
Program.csto the root of your application project. - Add this code to the
Program.cs:
public static class Program { [STAThread] public static Task Main(string[] args) { var builder = new WindowsAppSdkHostBuilder<App>(); builder.ConfigureServices( (_, collection) => { // If your main Window is named differently, change it here. collection.AddSingleton<MainWindow>(); } ); var app = builder.Build(); return app.StartAsync(); } }
- Set your
Program.csas the startup object by adding<StartupObject>HostedWindowsAppSdk.Program</StartupObject>to your project file. - Use the
CancelableApplicationas the base class of your application by modifying yourApp.xaml:
<host:CancelableApplication x:Class="HostedWindowsAppSdk.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:host="using:CommunityToolkit.Extensions.Hosting" xmlns:local="using:HostedWindowsAppSdk"> <Application.Resources> </Application.Resources> </host:CancelableApplication>
- Update your App.xaml.cs to use dependency injection.
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args) { // Get window from Dependency Injection. _mWindow = Services.GetRequiredService<MainWindow>(); _mWindow.Activate(); }
Notes
The WindowsAppSdkHost uses several features of the Microsoft.Extensions ecosystem:
- Includes all configuration resources defined for the
DefaultHostBuilder. - Registers the required
CancellableApplicationwith dependency injection. - Manages the lifecycle of the Application in the
StartAsyncmethod of theWindowsAppSdkHost. - Write unhandled errors to default
ILogger. TheIloggercan be obtained from the staticServicesproperty of theCancellableApplicationafter building the app.
TODO
I need help getting the project template formatted correctly for dotnet new.
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 4
Replies: 4 comments 6 replies
-
I like this a lot! This is something that is sorely missed in the current App SDK experience and I would love to see it show up in the SDK proper some day to align with other modern .NET project types.
My one question is how feasible is it to allow the elimination of App.xaml? In WinUI, App.xaml by default seems to exist solely to merge resource dictionaries, so it would be nice to avoid the file completely through a ConfigureServices-esque method like ConfigureXamlResources.
Beta Was this translation helpful? Give feedback.
All reactions
-
The Xaml file is unnecessary, but you must still declare an application container, which needs to be an instance of CancelableApplication to use this host.
Beta Was this translation helpful? Give feedback.
All reactions
-
There hasn't been much activity on this discussion here, it generated a lot more on Reddit. Is this just something that WinAppSdk devs don't care about?
Beta Was this translation helpful? Give feedback.
All reactions
-
I just found this idea thread after searching to see if anyone has done this exact thing already. So, I am very interested in this.
Beta Was this translation helpful? Give feedback.
All reactions
-
It's completed and ready to go.
Beta Was this translation helpful? Give feedback.
All reactions
-
Sorry @sharpninja, we haven't done much in terms of planning for the next release of the Toolkit yet. We also haven't figured out a strategy for anything specific to the Windows App SDK yet as the platform transitions from UWP to WinUI 3. You can see our current list of plans summary here #4486.
It does seem you've been getting some feedback and interest though, so that's good! Have you thought about adding a sample/example to your repo as well?
@nmetulev @Arlodotexe @Sergio0694 curious on your thoughts on this too?
Beta Was this translation helpful? Give feedback.
All reactions
-
There is one in the Tests.
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 1
-
Getting into the official toolkit would be nice from an enterprise consumer point of view, but it's not mandatory.
As I'm going through this, I may end up with suggestions around handling launch parameters, but I need to review/learn the sdk method for doing that before I could begin to suggest changes to the host.
Beta Was this translation helpful? Give feedback.
All reactions
-
I'm a bit confused with how much of the code was re-written for the WindowsUiAppSdkHost and WindowsAppSdkHostBuilder. Don't take me wrong that this is an important suggestion and it is required to even be able to use things such as the EntityFramework, but it is way too complicated for what it needs to be. We just nee to have a Main and use most of the HostApplicationBuilder features and it's a working WinUI App. No other changes needed,
Maybe I'm missing something?
Beta Was this translation helpful? Give feedback.
All reactions
-
In the executable assembly:
<PropertyGroup> <!-- Use our own Main entry point so we can control the HostBuilder and make the EntityFramework work --> <DefineConstants>DISABLE_XAML_GENERATED_MAIN</DefineConstants> <StartupObject>Oxygen.Editor.MainProgram</StartupObject> </PropertyGroup>
In the MainProgram.cs:
{ [DllImport("Microsoft.ui.xaml.dll")] private static extern void XamlCheckProcessRequirements(); private static HostApplicationBuilder CreateBuilder(string[] args) { var builder = new HostApplicationBuilder(args); builder.Configuration.SetBasePath(finder.ProgramData) .AddJsonFile("appsettings.json") .SetBasePath(finder.LocalAppData) .AddJsonFile("LocalSettings.json", true) .SetBasePath(finder.ProgramData) .AddJsonFile( $"{Assembly.GetAssembly(typeof(ProjectBrowserSettings))!.GetName().Name}/Config/ProjectBrowser.config.json"); builder.Services.... // TODO: add services builder.Services.AddSqlite<PersistentState>($"Data Source={dbPath}; Mode=ReadWriteCreate"); return builder; } [STAThread] private static void Main(string[] args) { var builder = CreateBuilder(args); var host = builder.Build(); Ioc.Default.ConfigureServices(host.Services); host.StartAsync() .GetAwaiter() .GetResult(); void OnAppOnUnhandledException(object sender, UnhandledExceptionEventArgs args) { // TODO: handle unhandled exceptions args.Handled = false; } XamlCheckProcessRequirements(); WinRT.ComWrappersSupport.InitializeComWrappers(); Application.Start( _ => { try { var context = new DispatcherQueueSynchronizationContext(DispatcherQueue.GetForCurrentThread()); SynchronizationContext.SetSynchronizationContext(context); var app = new App(); app.UnhandledException += OnAppOnUnhandledException; } catch (Exception ex) { Debug.WriteLine($"Error application start callback: {ex.Message}."); } }); } }
Voila.
Beta Was this translation helpful? Give feedback.