在Windows系统上注销用户后立即将系统发送到睡眠状态

时间:2012-10-19 02:11:39

标签: c# c++ sleep logoff

我有一个与用户模式模块一起运行的服务应用程序。该软件允许执行专门的电源操作,用户模式代码首先记录Windows用户,然后服务应用程序将系统置于睡眠模式。

此方案在某些系统上运行正常,但在其他系统上,睡眠操作失败。有时睡眠成功,但是当我唤醒系统并尝试再次执行时,睡眠API(SetSuspendState)挂起并且永远不会返回,同时系统仍然可以运行。

在进行测试时,我提出了一个硬编码延迟(使用Sleep(5000)API)似乎解决了大多数系统上的问题,但我仍然在其他系统上获得相同的结果。在这种情况下,我讨厌引入更长的延迟,因为它并没有真正解决问题,或者回答了为什么它首先发生的问题。另外,我确信那里有一个“慢”系统,即使10秒也不够......

那么,有没有人知道如何在睡眠API中修复这些失败?

PS。我在最新版本的Windows 7上运行测试。

3 个答案:

答案 0 :(得分:1)

利用SystemEvents Class ..我希望它对你有用..

Microsoft.Win32.SystemEvents.SessionEnded+=
                       new SessionEndedEventHandler(SystemEvents_SessionEnded);

和处理程序方法..

private void SystemEvents_SessionEnded(object sender, SessionEndedEventArgs e)
{
    if (e.Reason == SessionEndReasons.Logoff)
    {
        //this may sleep the system even when user logs off manually.
        Application.SetSuspendState(PowerState.Suspend, true, true);
    }
}

您需要导入using Microsoft.Win32;命名空间

答案 1 :(得分:0)

可能会阻止系统进入睡眠状态。司机可以禁止系统睡觉,有些系统根本无法入睡。

当遇到SetSuspendState不运行的情况时,运行“powercfg -energy”和“powercfg -requests”。该实用程序在诊断睡眠问题时非常方便,因此您还应该查看“powercfg /?”看到它的所有特殊能力。

答案 2 :(得分:-1)

我必须发布这个作为我自己问题的答案,因为这个解决方案对我有用。这是一种有点麻烦的方法,所以如果有人可以发布不同的解决方案,我会很感激。

简而言之,在注销用户之前,需要收集会话ID。然后为用户帐户发出API以便注销,同时需要监听并等待来自另一个线程的WTS_SESSION_LOGOFF通知,并继续这样做,直到会话(先前收集的)被注销。

但这不是全部。由于某些未知原因(我无法找到文档),我们需要等待具有WTSConnected状态且没有用户名的会话。只有这样我们才能调用SetSuspendState进行睡眠或休眠。