如何实现MAUI应用在MacOS(Mac Catalyst)下后台运行于系统托盘?
MAUI系统托盘应用:MacOS平台关闭窗口后保留托盘运行的实现方案
我正在开发一款可运行于系统托盘的MAUI应用,已在Windows平台实现关闭主窗口后仍保留系统托盘运行的功能,但MacOS平台的对应功能无法完成。开发时参考了WeatherTwentyOne项目构建系统托盘,以下是Windows平台的实现代码:
public App() { InitializeComponent(); MainPage = new AppShell(); } protected override Window CreateWindow(IActivationState activationState) { Window window = base.CreateWindow(activationState); #if WINDOWS window.Created += (s, e) => { var handle = WinRT.Interop.WindowNative.GetWindowHandle(window.Handler.PlatformView); var id = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(handle); var appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(id); appWindow.Closing += (s, e) => { e.Cancel = true; appWindow.Hide(); }; }; #endif return window; }
MacOS平台实现方案
1. 拦截窗口关闭事件,阻止应用退出
在CreateWindow方法中添加MacOS平台专属代码,拦截窗口断开场景的事件,取消默认退出行为并隐藏窗口:
protected override Window CreateWindow(IActivationState activationState) { Window window = base.CreateWindow(activationState); #if WINDOWS window.Created += (s, e) => { var handle = WinRT.Interop.WindowNative.GetWindowHandle(window.Handler.PlatformView); var id = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(handle); var appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(id); appWindow.Closing += (s, e) => { e.Cancel = true; appWindow.Hide(); }; }; #elif MACCATALYST window.Created += (s, e) => { var platformWindow = window.Handler.PlatformView as UIKit.UIWindow; platformWindow.WindowScene.Delegate = new WindowSceneDelegate(platformWindow); }; #endif return window; }
2. 实现自定义WindowSceneDelegate
创建一个继承自UIKit.UIWindowSceneDelegate的类,重写WillDisconnect方法来控制窗口关闭时的行为:
#if MACCATALYST public class WindowSceneDelegate : UIKit.UIWindowSceneDelegate { private readonly UIKit.UIWindow _window; public WindowSceneDelegate(UIKit.UIWindow window) { _window = window; } public override void WillDisconnect(UIKit.UIScene scene, UIKit.UISceneSession session, UIKit.UISceneDisconnectOptions options) { if (options.ShouldDisconnect) { // 隐藏窗口而非关闭应用 _window.Hidden = true; // 维持应用后台存活 UIKit.UIApplication.SharedApplication.SetKeepAliveTimeout(600, () => {}); } base.WillDisconnect(scene, session, options); } } #endif
3. 托盘图标点击恢复窗口
确保你的系统托盘实现中添加点击事件,用于重新显示隐藏的主窗口:
#if MACCATALYST // 假设已初始化NSStatusItem作为托盘图标 var statusItem = AppKit.NSStatusBar.SystemStatusBar.CreateStatusItem(AppKit.NSStatusItemLength.Variable); statusItem.Button.Image = AppKit.NSImage.ImageNamed("TrayIcon"); // 替换为你的托盘图标名称 statusItem.Button.Activated += (s, e) => { var mainWindow = App.Current.Windows.FirstOrDefault(); if (mainWindow != null) { var platformWindow = mainWindow.Handler.PlatformView as UIKit.UIWindow; platformWindow.Hidden = false; platformWindow.MakeKeyAndVisible(); } }; #endif
额外配置
- 打开MacOS项目的
Info.plist,添加UIApplicationExitsOnSuspend键并设置值为NO,防止应用进入后台后被系统终止 - 确保托盘图标已添加到MacOS项目的资源文件中,路径引用正确
内容的提问来源于stack exchange,提问作者Irasil
相关产品推荐
相关产品推荐

