ShutdownBlockReasonCreate – 创建在注销/关闭期间显示的多个原因

我在我的C#应用​​程序中使用ShutdownBlockReasonCreate来警告用户,如果注销/关闭将影响我的应用程序中当前正在运行的方法。

我有两种方法可以警告用户:“上传”方法和“下载”方法。

如果用户启动长上传,我将ShutdownBlockReasonCreate设置为“上传当前正在运行”之类的消息。

我遇到的问题是,如果用户在长上传运行时启动简单下载,则还会再次调用ShutdownBlockReasonCreate,并显示“正在下载当前正在运行”的消息。

这会覆盖原始的“上载当前正在运行”消息。 因此,当我的下载方法完成,并且我调用ShutdownBlockReasonDestroy时,即使上传仍在运行,用户也可以突然关闭并注销。

我希望能够使用我可以调用的可选参数调用ShutdownBlockReasonCreate,这样我就可以发送多个字符串,说明为什么程序不允许窗口关闭或注销。

因此,当用户进行注销时,我希望它显示:

“目前正在上传”
“下载目前正在运行”

如果上传和下载都在运行。

有人可以修改我的代码,告诉我如何做到这一点? 如果我能传递“this.Handle”以外的其他内容; 也许我可以做到这一点,但我不确定如何做到这一点。

//http://blogs.msdn.com/b/oldnewthing/archive/2012/06/14/10319617.aspx //http://bartdesmet.net/blogs/bart/archive/2006/10/25/Windows-Vista-_2D00_-ShutdownBlockReasonCreate-in-C_2300_.aspx [DllImport("user32.dll")] public extern static bool ShutdownBlockReasonCreate(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)] string pwszReason); [DllImport("user32.dll")] public extern static bool ShutdownBlockReasonDestroy(IntPtr hWnd); private bool isBlocked = false; protected override void WndProc(ref Message aMessage) { const int WM_QUERYENDSESSION = 0x0011; const int WM_ENDSESSION = 0x0016; if (isBlocked && (aMessage.Msg == WM_QUERYENDSESSION || aMessage.Msg == WM_ENDSESSION)) return; base.WndProc(ref aMessage); } private void StopShutdown(string strMessage) { try { //strMessage == Message to display in shutdown/logoff box if (ShutdownBlockReasonCreate(this.Handle, strMessage)) { isBlocked = true; Console.WriteLine("++ StopShutdown successful"); } else Console.WriteLine("++ StopShutdown failed"); } catch (Exception ext) { MessageBox.Show("++ StopShutdown Error: " + ext.Message + " " + ext.StackTrace); } } private void ResetShutdown() { try { if (ShutdownBlockReasonDestroy(this.Handle)) { isBlocked = false; Console.WriteLine("++ ResetShutdown successful"); } else Console.WriteLine("++ ResetShutdown failed"); } catch (Exception ext) { MessageBox.Show("++ ResetShutdown Error: " + ext.Message + " " + ext.StackTrace); } } private void button1_Click(object sender, EventArgs e) { StopShutdown("Upload in Progress"); MessageBox.Show("Upload in Progress"); ResetShutdown(); } private void button2_Click(object sender, EventArgs e) { StopShutdown("Download in Progress"); MessageBox.Show("Download in Progress"); ResetShutdown(); } 

为了确保显示正确的消息,并且如果正在进行阻止操作,则始终显示消息(并且阻止关闭),您需要仔细跟踪系统中发生的情况。

例如,假设您可以同时运行任意数量的上载和下载。 在这种情况下,您的StopShutdown()方法需要确定当前正在进行的操作。 如果至少有一次上传但没有下载,请将消息设置为“正在上传”。 如果至少有一次下载但没有上传,请将消息设置为“正在下载”。 如果每个中至少有一个,则将消息设置为“正在上载和下载”。

ResetShutdown()方法中,您需要再次检查哪些操作仍在进行中。 如果没有,那么你应该销毁原因,并将isBlocked设置为false 。 否则,您应该根据当前正在运行的内容调整消息,并将isBlockedtrue

通过这样做,您可以确保两者都具有正确的关闭方法,然后只有在程序未处于应阻止关闭的操作过程中时才允许关闭。

(此外,您应该记住,即使您“阻止”系统,用户也可以自由“强制关闭”系统,因此更安全的方法通常是尝试暂停您正在执行的操作,然后在以后恢复。)