【声明】CSDN只做转发不做时时更新,最新博客请关注博客园 .NET 阻止Windows关机以及阻止失败的一些原因 - 唐宋元明清2188 - 博客园
本文主要介绍Windows在关闭时,如何正确、可靠的阻止系统关机以及关机前执行相应业务
Windows关机,默认会给应用几s的关闭时间,但有一些场景需要在关机/重启前执行更长时间的业务逻辑,确保下次开机时数据的一致性以及可靠性。我司目前业务也用到关机阻止,但这块之前并未梳理清楚,依赖BUG编程,导致后续维护项目时关机这块又会出现新问题。
统一整理,以下是实现这一需求的几种方法,
1. Windows消息Hook勾子
1 public MainWindow() 2 { 3 InitializeComponent(); 4 Loaded += OnLoaded; 5 } 6 7 private void OnLoaded(object sender, RoutedEventArgs e) 8 { 9 Loaded -= OnLoaded; 10 var source = PresentationSource.FromVisual(this) as HwndSource; 11 source?.AddHook(WndProc); 12 } 13 const int WM_QUERYENDSESSION = 0x11; 14 const int WM_ENDSESSION = 0x16; 15 private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 16 { 17 if (msg == WM_QUERYENDSESSION) 18 { 19 var handle = new WindowInteropHelper(this).Handle; 20 ShutdownBlockReasonCreate(handle, "应用保存数据中,请等待..."); 21 // 可以在这里执行你的业务逻辑 22 bool executeSuccess = ExecuteShutdownWork(); 23 // 返回0表示阻止关机,1表示允许关机 24 handled = true; 25 return executeSuccess ? (IntPtr)1 : (IntPtr)0; 26 } 27 return (IntPtr)1; 28 } 29 30 private bool ExecuteShutdownWork() 31 { 32 Thread.Sleep(TimeSpan.FromSeconds(20)); 33 //测试,默认返回操作失败 34 return false; 35 } 36 37 [DllImport("user32.dll")] 38 private static extern bool ShutdownBlockReasonCreate(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)] string reason); 39 [DllImport("user32.dll")] 40 private static extern bool ShutdownBlockReasonDestroy(IntPtr h