Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

HostBuilder and Host for Windows App SDK #4358

sharpninja started this conversation in Ideas
Discussion options

@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)

  1. Add <DefineConstants>DISABLE_XAML_GENERATED_MAIN</DefineConstants> in the main PropertyGroup of your applications project file.
  2. Add reference to CommunityToolkit.Extensions.Hosting.WindowsAppSdk
  3. Add Program.cs to the root of your application project.
  4. 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();
 }
}
  1. Set your Program.cs as the startup object by adding <StartupObject>HostedWindowsAppSdk.Program</StartupObject> to your project file.
  2. Use the CancelableApplication as the base class of your application by modifying your App.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>
  1. 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:

  1. Includes all configuration resources defined for the DefaultHostBuilder.
  2. Registers the required CancellableApplication with dependency injection.
  3. Manages the lifecycle of the Application in the StartAsync method of the WindowsAppSdkHost.
  4. Write unhandled errors to default ILogger. The Ilogger can be obtained from the static Services property of the CancellableApplication after building the app.

TODO

I need help getting the project template formatted correctly for dotnet new.

You must be logged in to vote

Replies: 4 comments 6 replies

Comment options

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.

You must be logged in to vote
1 reply
Comment options

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.

Comment options

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?

You must be logged in to vote
5 replies
Comment options

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.

Comment options

It's completed and ready to go.

Comment options

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?

Comment options

There is one in the Tests.

Comment options

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.

Comment options

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?

You must be logged in to vote
0 replies
Comment options

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.

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

AltStyle によって変換されたページ (->オリジナル) /