C# ShutdownBlockReasonCreate-创建在注销/关闭期间显示的多个原因
我在我的C#应用程序中使用ShutdownBlockReasonCreate来警告用户,如果注销/关闭将影响我的应用程序中当前正在运行的方法 我有两种方法可以警告用户:“上传”方法和“下载”方法 如果用户开始长时间上传,我会用“Upload is current running”(上传当前正在运行)这样的消息设置ShutdownBlockReasonCreate 我遇到的问题是,如果用户在长时间上载运行时启动一个简单下载,也会再次调用ShutdownBlockReasonCreate,并显示类似“download is current running”的消息 这将覆盖原始的“上载当前正在运行”消息。因此,当我的下载方法完成后,我调用ShutdownBlockReasonDestroy,用户现在可以突然关闭并注销,即使上传仍在运行 我希望能够使用一个可选参数调用ShutdownBlockReasonCreate,这样我就可以向它发送多个字符串,说明为什么程序不允许windows关闭或注销 因此,当用户要注销时,我希望它显示: “上载当前正在运行”C# ShutdownBlockReasonCreate-创建在注销/关闭期间显示的多个原因,c#,C#,我在我的C#应用程序中使用ShutdownBlockReasonCreate来警告用户,如果注销/关闭将影响我的应用程序中当前正在运行的方法 我有两种方法可以警告用户:“上传”方法和“下载”方法 如果用户开始长时间上传,我会用“Upload is current running”(上传当前正在运行)这样的消息设置ShutdownBlockReasonCreate 我遇到的问题是,如果用户在长时间上载运行时启动一个简单下载,也会再次调用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
。否则,您应该根据当前运行的内容调整消息,并将isBlocked
保留为true
通过这样做,您可以确保两个都有正确的关机方法,如果程序不在关机操作的中间,也只允许关机。
(此外,您应该记住,用户可以自由地“强制关闭”系统,即使您“阻止”了它,因此更安全的方法通常是尝试暂停您正在做的事情,然后在稍后继续。)以确保显示正确的消息,并且始终显示消息(并防止关机)如果正在进行阻塞操作,则需要仔细跟踪系统中发生的情况 例如,假设您可以同时运行任意数量的上载和下载。在这种情况下,您的
StopShutdown()
方法需要确定当前正在发生的操作。如果至少有一个上载,但没有下载,则将消息设置为“正在上载”。如果至少有一个下载,但没有上载,则将消息设置为“正在下载”。如果至少有一个上载,则将消息设置为“正在上载和下载”
在ResetShutdown()
方法中,需要再次检查哪些操作仍在进行中。如果没有,则应销毁原因,并将isBlocked
设置回false
。否则,您应该根据当前运行的内容调整消息,并将isBlocked
保留为true
通过这样做,您可以确保两个都有正确的关机方法,如果程序不在关机操作的中间,也只允许关机。
(此外,您应该记住,用户可以自由地“强制关闭”系统,即使您“阻止”了它,因此更安全的方法通常是尝试暂停您正在做的事情,然后在稍后恢复。)只需根据当前运行的内容设置消息(您需要在程序的中心位置跟踪)只有在没有零阻塞操作的情况下才能销毁原因。我试过了,但没有成功。我将启动ShutdownBlockReasonCreate(this.Handle,strMessage)时使用的同一字符串传递给ShutdownBlockReasonDestroy(this.Handle,strMessage),但它不起作用。只注册了一条消息,一旦我销毁了该消息,计算机将允许注销/关机,即使我使用不同的消息启动了另一个ShutdownBlockReasonCreate。我将发布一个更好地描述我意思的答案。这种方法不可能“不工作”:)一个进程只能产生一条消息。您正在编写的代码将永远不会被使用,用户将始终覆盖并强制关闭。只需根据当前正在运行的内容设置消息(您需要在程序的中心位置跟踪该消息),并且仅在没有零阻塞操作的情况下销毁原因。我尝试了,但没有成功。我将启动ShutdownBlockReasonCreate(this.Handle,strMessage)时使用的同一字符串传递给ShutdownBlockReasonDestroy(this.Handle,strMessage),但它不起作用。仅注册了一条消息,一旦我销毁该消息,计算机将允许注销/关机,即使我使用不同的消息启动了另一个ShutdownBlockReasonCreate。我