.NET MAUI(WinUI3)自定义URI协议重复启动实例问题求助
解决.NET MAUI Windows端自定义URI协议的单实例与事件触发问题
针对你遇到的Windows端自定义URI协议启动新实例、无法触发OnAppLinkRequestReceived的问题,可通过以下步骤解决:
1. 实现单实例与协议激活事件转发
在Windows项目的Platforms/Windows/App.xaml.cs中,利用Windows App SDK的AppInstance实现单实例逻辑,并捕获协议激活事件:
using Microsoft.Maui; using Microsoft.Windows.AppLifecycle; using Windows.ApplicationModel.Activation; using Windows.UI.Xaml; using System; namespace YourAppNamespace.WinUI; public partial class App : MauiWinUIApplication { private AppInstance? _currentInstance; public App() { InitializeComponent(); SetupSingleInstanceAndProtocolHandling(); } protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); private void SetupSingleInstanceAndProtocolHandling() { // 注册唯一实例标识 _currentInstance = AppInstance.FindOrRegisterInstanceForKey("DayPlanner_InstanceKey"); if (!_currentInstance.IsCurrent) { // 转发激活请求到已有实例,退出新实例 AppInstance.GetCurrent().RedirectActivationTo(_currentInstance); Environment.Exit(0); return; } // 订阅实例激活事件 _currentInstance.Activated += OnInstanceActivated; } private void OnInstanceActivated(object? sender, AppActivationArguments args) { if (args.Kind != ActivationKind.Protocol) return; var protocolArgs = args.Data as ProtocolActivatedEventArgs; if (protocolArgs?.Uri == null) return; // 手动触发MAUI的AppLink事件 var mauiApp = (Microsoft.Maui.Controls.App)MauiContext!.Services.GetRequiredService<IApplication>(); mauiApp.OnAppLinkRequestReceived(protocolArgs.Uri); // 激活当前窗口 Window.Current?.Activate(); } // 处理首次启动时的协议激活 protected override void OnLaunched(LaunchActivatedEventArgs args) { base.OnLaunched(args); if (args.Kind == ActivationKind.Protocol) { var protocolArgs = args as ProtocolActivatedEventArgs; if (protocolArgs?.Uri != null) { var mauiApp = (Microsoft.Maui.Controls.App)MauiContext!.Services.GetRequiredService<IApplication>(); mauiApp.OnAppLinkRequestReceived(protocolArgs.Uri); } } } }
2. 确保MAUI端正确处理AppLink事件
在MAUI项目根目录的App.xaml.cs中,重写OnAppLinkRequestReceived以处理令牌参数:
using Microsoft.Maui.Controls; using System; using System.Web; // 需添加System.Web引用,或用其他方式解析QueryString namespace YourAppNamespace; public partial class App : Application { public App() { InitializeComponent(); MainPage = new MainPage(); } protected override void OnAppLinkRequestReceived(Uri uri) { // 解析令牌参数 var queryParams = HttpUtility.ParseQueryString(uri.Query); var token = queryParams["token"]; var refreshToken = queryParams["refreshToken"]; // 执行你的认证逻辑,比如保存令牌、跳转页面等 if (!string.IsNullOrEmpty(token)) { // 示例:保存令牌到本地存储 Preferences.Set("AuthToken", token); Preferences.Set("RefreshToken", refreshToken); // 跳转到主页或认证后的页面 MainPage = new MainPage(); } base.OnAppLinkRequestReceived(uri); } }
3. 检查Package.appxmanifest配置
确保协议扩展处于正确的层级(在<Application>节点内),并补充必要的显示名称:
<Package ...> <Applications> <Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="YourAppNamespace.WinUI.App"> <!-- 其他配置 --> <Extensions> <uap:Extension Category="windows.protocol"> <uap:Protocol Name="dayplanner"> <uap:DisplayName>Day Planner 协议</uap:DisplayName> </uap:Protocol> </uap:Extension> </Extensions> </Application> </Applications> </Package>
4. 测试前的必要操作
- 卸载电脑上已安装的旧版本应用,避免配置残留
- 重新部署MAUI应用到Windows平台
- 测试时使用
dayplanner://?token=xyz&refreshToken=abc链接,确认不会启动新实例,且令牌参数能被正确捕获
内容的提问来源于stack exchange,提问作者SoldatXwing
相关产品推荐
相关产品推荐

