检测PowerModeChange并等待执行

时间:2015-05-14 20:02:19

标签: c# winapi power-management win32-process

我想在计算机挂起时运行一些保存例程。因此,我使用OnPowerChange-Event来检测它何时挂起并恢复。不幸的是,我保存例程需要3-5秒才能执行。

当我收到暂停事件时,计算机会在1-2秒内关闭,而我的例行程序不会完全执行。

如何在我的例程结束前阻止暂停?

SystemEvents.PowerModeChanged += OnPowerChange;


private void OnPowerChange(object s, PowerModeChangedEventArgs e)
{

    switch (e.Mode)
    {
        case PowerModes.Resume:
            switchEdifier(true);
            break;
        case PowerModes.Suspend:
            switchEdifier(false);
            break;
    }
}

1 个答案:

答案 0 :(得分:1)

有一些非托管API可以帮助解决此问题,特别是ShutdownBlockReasonCreateShutdownBlockReasonDestroy

重要的是要注意这两个函数必须配对,当你调用一个时,你必须确保你调用另一个(例如,如果发生异常),否则关闭可能会无限期地被阻止。

这将导致出现一个对话框,告诉用户哪些程序阻止关闭,以及它的原因。重要的是你要快速完成工作并离开,因为用户可以选择按下强制关机"按钮,他们经常使用。

以下是使用它的示例:

[DllImport("user32.dll", SetLastError=true)]
static extern bool ShutdownBlockReasonCreate(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)] string reason);

[DllImport("user32.dll", SetLastError=true)]
static extern bool ShutdownBlockReasonDestroy(IntPtr hWnd);

//The following needs to go in a Form class, as it requires a valid window handle
public void BlockShutdownAndSave()
{
    //If calling this from an event, you may need to invoke on the main form
    //because calling this from a thread that is not the owner of the Handle
    //will cause an "Access Denied" error.

    try
    {
        ShutdownBlockReasonCreate(this.Handle, "You need to be patient.");
        //Do your saving here.
    }
    finally
    {
        ShutdownBlockReasonDestroy(this.Handle);
    }
}

由于用户通常不会阅读长消息,因此鼓励使用短字符串。引起注意的东西,比如"保存数据"或"刷新磁盘更改"。请注意,无论如何我都要做一个不耐烦的用户"按钮。