如何在WinUI中阻止Windows关机直至完成指定操作?
如何在WinUI中阻止用户关闭Windows系统直至完成特定操作
可以实现,WinUI(尤其是桌面版)能实现类似WinForms的效果,核心是通过监听系统关闭相关的Win32消息来拦截关闭请求,以下是具体实现方案:
核心思路
系统在关闭前会向所有顶层窗口发送WM_QUERYENDSESSION消息,通过拦截这个消息并返回特定值,就能阻止系统关闭,直到你的特定操作完成。
具体实现(WinUI 3桌面应用)
在WinUI 3桌面应用中,你需要通过窗口句柄注册自定义的消息处理逻辑:
- 首先添加必要的引用和导入:
using Microsoft.UI.Xaml; using System.Runtime.InteropServices;
- 在你的主窗口类中实现消息拦截:
private IntPtr _hwnd; private WndProcDelegate _wndProcDelegate; private IntPtr _oldWndProc; // 定义窗口过程委托 private delegate IntPtr WndProcDelegate(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); protected override void OnActivated(WindowActivatedEventArgs args) { base.OnActivated(args); // 仅初始化一次窗口消息处理 if (_hwnd == IntPtr.Zero) { _hwnd = WindowNative.GetWindowHandle(this); _wndProcDelegate = WndProc; _oldWndProc = SetWindowLongPtr(_hwnd, GWLP_WNDPROC, Marshal.GetFunctionPointerForDelegate(_wndProcDelegate)); } } private IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) { const uint WM_QUERYENDSESSION = 0x0011; const uint WM_ENDSESSION = 0x0016; switch (msg) { case WM_QUERYENDSESSION: // 检查特定操作是否完成 if (!IsCriticalOperationCompleted()) { // 返回0告知系统阻止关闭 // 同时弹出提示告知用户 DispatcherQueue.TryEnqueue(() => { var dialog = new ContentDialog { Title = "操作未完成", Content = "请先完成当前的关键操作,再尝试关闭系统。", PrimaryButtonText = "确定", XamlRoot = Content.XamlRoot }; _ = dialog.ShowAsync(); }); return IntPtr.Zero; } break; case WM_ENDSESSION: // 如果允许关闭,这里可以执行收尾清理操作 break; } // 调用原窗口处理逻辑 return CallWindowProc(_oldWndProc, hWnd, msg, wParam, lParam); } // 导入Win32 API [DllImport("user32.dll", SetLastError = true)] private static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong); [DllImport("user32.dll")] private static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); private const int GWLP_WNDPROC = -4; // 自定义方法:判断特定操作是否完成 private bool IsCriticalOperationCompleted() { // 替换为你的实际判断逻辑,比如检查任务是否完成、文件是否保存等 return false; }
注意事项
- 该方案仅适用于WinUI 3桌面应用(包括打包为MSIX或非打包的版本);UWP版WinUI受沙箱限制,无法强制阻止系统关闭,只能通过弹窗提示用户。
- 必须给用户明确的提示,避免用户困惑系统无法关闭的原因。
- 不要滥用此功能,仅在用户进行未保存的关键操作等必要场景下使用。
内容的提问来源于stack exchange,提问作者aklevans
相关产品推荐
相关产品推荐

