如何使用C#关闭正在运行的Windows屏幕保护程序?

4
好的,我找到了一些关于检测屏幕保护程序并在需要时关闭它的代码。但是,在Windows 7电脑上似乎无法正常工作。有人知道如何修改这段代码吗?或者提供新的代码来解决这个问题吗?
我的应用程序旨在在后台运行,直到发生特定事件,然后创建并显示全屏通知。即使当前正在运行屏幕保护程序,也需要显示此通知。

2
如果您想显示消息,但系统要求输入密码才能退出屏幕保护程序,会发生什么情况呢?希望您能充分控制相关的计算机,这样就不会出现问题,但我猜这可能会破坏您的计划... - ZombieSheep
不用担心。这些盒子上没有密码策略。如果由于某种原因有密码,如果输入密码框弹出,我也不会生气。 - IronicMuffin
4个回答

4
最简单的方法是通过调用SendInput()函数模拟一个鼠标移动事件,其中x和y坐标均为0。

这听起来很简单。我会试一试。 - IronicMuffin
像魔法一样好用。对于那些在.NET世界中的人:Cursor.Position = new System.Drawing.Point(0, 0); - IronicMuffin
有趣的小解决方案,得记住这个!+1 - Daniel Frear
3
无法在Windows 8上运行。 :( - Kumar Ravi

2
以下问题可能会提供一些见解:
如何通过代码(在cmd中)打开屏幕保护程序(windows 7)?
然而,如果机器被锁定怎么办?我认为除非它实际上是一个屏幕保护程序(即使是这样也可能不可能),否则您将无法在锁定屏幕的顶部显示任何应用程序。

这是给繁忙的电脑店员的。它应该永远不会被锁定。如果它被锁定了,那么我们就必须处理它。现在我只需要关闭一个没有密码保护的屏幕保护程序。不过我会查看这个问题的。谢谢! - IronicMuffin
如果我需要对屏幕保护程序施加更多控制,或者重新启用它,这很好...但我将把David Heffernan的回答标记为答案。我正在寻找简单、快速和有效的方法。谢谢! - IronicMuffin
没问题,这只是提供信息而不是完整答案 :) - Daniel Frear

1

1
你有没有读过这篇文章?那个示例代码是针对Windows 95的。 - Mark Ransom
1
@Mark:是的,我读了这篇文章,所以我知道在屏幕保护没有密码保护的情况下,适用于Win95的方法也适用于任何版本的Windows(NT、2k等)。由于OP说他们不会设置密码,因此可以使用这种方法。 - Gabe

0
使用SetThreadExecutionState这个winAPI告诉操作系统线程正在使用,即使用户没有与计算机交互。这将防止屏幕保护程序出现并停止计算机自动挂起。

使应用程序通知系统它正在使用,从而在应用程序运行时防止系统进入睡眠或关闭显示器。

有一系列的标志来指定当前线程的新状态:

  • ES_AWAYMODE_REQUIRED (0x00000040):启用离开模式。
  • ES_DISPLAY_REQUIRED (0x00000002):通过重置显示器空闲计时器强制打开显示器。
  • ES_SYSTEM_REQUIRED (0x00000001):通过重置系统空闲计时器强制系统处于工作状态。
  • ES_CONTINUOUS (0x80000000):通知系统设置的状态应保持有效,直到下一个使用ES_CONTINUOUS和其他状态标志之一的调用被清除。

因为这是WinAPI,所以你必须进行 PInvoke

[DllImport("kernel32.dll", CharSet = CharSet.Auto,SetLastError = true)]
static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags);

用户定义类型:

[FlagsAttribute]
public enum EXECUTION_STATE :uint
{
   ES_AWAYMODE_REQUIRED = 0x00000040,
   ES_CONTINUOUS = 0x80000000,
   ES_DISPLAY_REQUIRED = 0x00000002,
   ES_SYSTEM_REQUIRED = 0x00000001
}

这里是调用过程:

//To stop screen saver and monitor power off event
//You can combine several flags and specify multiple behaviors with a single call
SetThreadExecutionState(EXECUTION_STATE.ES_DISPLAY_REQUIRED | EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS);

//To reset or allow those event again you have to call this API with only ES_CONTINUOUS
SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS);//This will reset as normal

根据MSDN的说法,这个API是安全可用的。

系统会维护一个调用SetThreadExecutionState的应用程序计数器。系统会跟踪每个调用SetThreadExecutionState的线程并相应地调整计数器。如果该计数器达到零且没有任何用户输入,则系统进入睡眠状态。

如果应用程序在重置标志之前崩溃,系统将进行调整并自动重置。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接