延迟关机和锁屏

时间:2013-07-31 07:42:55

标签: c# wpf winapi windows-7 shutdown

项目:

我目前正在开发一个应用程序来警告用户,如果他离开(锁定屏幕或关闭)他的工作场所并将他的智能卡留在阅读器中。

如果smarcard当前在读者中,我能够通过使用WinAPI(WinSCard.dll)进行检测。

问题:

我读过(如果这是错误的,请纠正我)应用程序无法延迟锁定屏幕,因此我目前专注于延迟关机。

我现在遇到的问题是我需要延迟正在进行的关机以警告用户他已离开智能卡。

我尝试使用ShutdownBlockReasonCreate来延迟关机至少5秒钟Windows如此慷慨地让我。我的想法是,如果用户删除了他的智能卡,我的应用程序会调用ShutdownBlockReasonDestroy来继续关闭。

我实现了两种方法:

[DllImport("User32.dll", EntryPoint = "ShutdownBlockReasonCreate", 
           CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool ShutdownBlockReasonCreate(
    [In()]IntPtr wndHandle,
    [In()]string reason);

[DllImport("User32.dll", EntryPoint = "ShutdownBlockReasonDestroy", 
           CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool ShutdownBlockReasonDestroy(
    [In()]IntPtr wndHandle);

此外,我使用GetLastError来检查我以这种方式实现的错误:

[DllImport("Kernel32.dll", EntryPoint = "GetLastError", 
           CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern int GetLastError();

现在奇怪的是,如果我创造了原因

WinAPIMethoden.ShutdownBlockReasonCreate(
      new WindowInteropHelper(Application.Current.MainWindow).Handle, 
                              "Smartcard still in reader!");

然后显示错误

MessageBox.Show(WinAPIMethoden.GetLastError().ToString("X"));

它显示0表示ERROR_SUCCESS

到目前为止,一切似乎都很棒。 现在,如果我试图关闭PC,那么我的应用程序已经要求PC不应该立即关闭。

问题:

我做错了什么,以致ShutdownBlockReasonCreate无法正常工作?

或者是否有一种更好的方法可以阻止用户关闭PC,如果他的智能卡仍然存在,就像阻止他在卡片进入或类似的情况下启动关机一样?

TL; DR:

我尝试在用户将智能卡放入阅读器时阻止关机。 我使用ShutdownBlockReasonCreate但它似乎没有效果,尽管没有错误。

解决方案:

接受的答案引导我解决问题。

您必须创建cancle原因并为SystemEvents.SessionEnding订阅处理程序。 然后,此处理程序必须将e.Cancel设置为true

void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e)
{
    if (mgr.state == SmartcardState.Inserted)
    {
        e.Cancel = true;
    }
}

要在关机时执行程序,我使用gpendit.msc将其添加到关机脚本。 然后程序在所有程序终止后执行。看起来很奇怪,但是做了这件事。