Skip to content

WinUI3 项目使用 .NET Generic Host

Published: at 22:00

NuGet Gallery | Microsoft.Extensions.Hosting 8.0.1

.NET Generic Host - .NET | Microsoft Learn

本文用于记录使用 .NET Generic Host 来管理 WinUI3 项目。

管理 WPF 项目可以参考:

使用 Hosting 构建 WPF 程序 - prism 篇

WinUI3 + .NET Generic Host

1 添加一个文件,如 Program.cs,用于编写自定义的 Main 入口点。

using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace GamePad.App;
internal static class Program
{
static void Main(string[] args)
{
// TODO
}
}

2 配置 csproj, 禁用默认的程序启动入口,配置新的入口。

同时引入 Microsoft.Extensions.Hosting

<PropertyGroup>
<!-- 禁用默认入口点生成 -->
<DefineConstants>$(DefineConstants);DISABLE_XAML_GENERATED_MAIN</DefineConstants>
<StartupObject>GamePad.App.Program</StartupObject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0" />
</ItemGroup>

3 添加 WinUiHostedService 作为 Host 的一个服务

引用自 c# - Why doesn’t the .NET Generic Host stop when used with WinUI3? - Stack Overflow

using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml;
namespace GamePad.App;
public class WinUiHostedService<TApplication> : IHostedService, IDisposable
where TApplication : Application, new()
{
private readonly IHostApplicationLifetime _hostApplicationLifetime;
private readonly IServiceProvider _serviceProvider;
public WinUiHostedService(
IHostApplicationLifetime hostApplicationLifetime,
IServiceProvider serviceProvider
)
{
_hostApplicationLifetime = hostApplicationLifetime;
_serviceProvider = serviceProvider;
}
public void Dispose() { }
public Task StartAsync(CancellationToken cancellationToken)
{
var thread = new Thread(Main);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
private void Main()
{
WinRT.ComWrappersSupport.InitializeComWrappers();
Application.Start(
(p) =>
{
var context = new DispatcherQueueSynchronizationContext(
DispatcherQueue.GetForCurrentThread()
);
SynchronizationContext.SetSynchronizationContext(context);
var application = new TApplication();
}
);
_hostApplicationLifetime.StopApplication();
}
}

4 完成 Main 方法

internal static class Program
{
static void Main(string[] args)
{
Host.CreateDefaultBuilder()
.ConfigureServices(services =>
{
services.AddHostedService<WinUiHostedService<App>>();
})
.Build()
.Run();
}
}

prism

prism 目前还没有官方支持 WinUI3

Prism for WinUI 3 · PrismLibrary/Prism · Discussion #2675 · GitHub
GitHub - PrismLibrary/Prism

参考内容

GitHub - abdes/winui-override-main: A WinUI 3 visual studio solution for an application that uses a custom Main entry point instead of the default XAML entry point.

How to create a single-instanced WinUI app with C# - Windows apps | Microsoft Learn

c# - Why doesn’t the .NET Generic Host stop when used with WinUI3? - Stack Overflow


原文链接: https://blog.jgrass.cc/posts/winui3-net-host/

本作品采用 「署名 4.0 国际」 许可协议进行许可,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。