以编程方式中断活动的屏幕保护程序?
原因: 我正在开发一个需要在桌面上显示信息的紧急警报应用程序。 当客户端收到警报时,会弹出一个窗口。 如果屏幕保护程序处于活动状态或显示器处于待机状态,则警报将不可见。 我想知道是否可以通过某种程序化的鼠标移动或系统调用唤醒计算机,以便警报可见。 我认为鼠标移动或按键唤醒它的原因是由于硬件中断,所以它可能是不可能的。
目前,该项目正在用C#实现。 我有兴趣了解适用于 Windows、MAC 和 Linux 的解决方案。
这是客户的要求。 我考虑过以下事项:
- 在大多数计算机上,用户在不活动后必须登录。 这些计算机不会收到警报
- 如果屏幕保护程序处于活动状态,则很有可能没人在使用计算机。
我并不是想:
- 阻止屏幕保护程序或节能模式一起被激活。
REASON:
I'm working on an emergency alert application that needs to display information on a desktop. When the client receives an alert, it pops up a window. If a screensaver is active or the monitor is in standby the alert will not be visible. I'm wondering if it's possible to wake the computer up via some sort of programatic mouse move or system call so that the alert would be visible. I think the reason a mouse move or keypress wakes it up is because of a hardware interrupt so it may not be possible.
Currently, the project is being implemented in C#.
I'm interested to hear about solutions for Windows, MAC, and Linux.
This is a customer request. I have considered the following:
- On most computers after inactivity, the user must login. Those computers will not get the alert
- There is a good chance that if a screensaver is active, then noone is at the computer anyway.
I am NOT trying to:
- Prevent a screensaver or energy savings mode to be activated all together.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
基于 fbonnet 所说的,要使用 C# 中的 kb 文章中显示的函数 pinvoke.net 网站是一个很棒的资源。 他们还有一篇关于
PostMessage
函数的文章这里< /a>.因此,让代码正常工作的基本方法可能是搜索 kb 文章中列出的函数pinvoke.net 网站。 或者您可以阅读这篇文章已经为您做到了这一点。< /强>
Building on what fbonnet said, to use the functions shown in the kb article in C# the pinvoke.net site is a great resource. They also have a article on the
PostMessage
function here.So the basic way of getting your code working could be searching the functions listed in the kb article on the pinvoke.net site. Or you can read this article has done that for you.
以编程方式中断屏幕保存的一种方法是移动鼠标光标。 然而,在 Windows 上,这并不像乍看起来那么简单。
Windows 操作系统具有对象层次结构。 层次结构的顶部是“Window Station”。 其正下方是“桌面”(不要与桌面文件夹混淆,甚至不要与显示该文件夹图标的桌面窗口混淆)。 您可以在 文档。
我提到这一点是因为通常只有一个桌面可以在任何给定时间接收和处理用户输入。 而且,当 Windows 由于超时而激活屏幕保护程序时,Windows 会创建一个新桌面来运行屏幕保护程序。
这意味着与任何其他桌面关联的任何应用程序(包括您编写的正在运行的程序)将无法将输入发送到新桌面,而无需进行一些额外的工作。 这项工作的性质取决于几个因素。 假设最简单的情况,创建的屏幕保护程序没有“恢复时显示登录屏幕”,并且没有通过远程连接或本地用户登录创建其他 Window Station,那么您可以向 Windows 请求活动桌面,附加将 Python 脚本复制到该桌面,移动鼠标,然后恢复到之前的桌面,以便脚本的其余部分按预期工作。
值得庆幸的是,执行此操作的代码比解释更容易:
但是,如果屏幕保护程序在单独的 Window Station 上运行,因为选择了“恢复时,显示登录屏幕”,或者另一个用户通过物理控制台连接或具有远程连接,然后连接并附加到活动桌面将需要提升程序,即使如此,根据其他因素,它可能需要特殊权限。
虽然这可能适用于给定的用例,但我将添加一般情况下的核心问题可能更正确地定义为询问“如何在屏幕保护程序不阻止该通知的情况下通知用户某事物的状态? ”。 这个问题的答案不是“导致屏幕保护程序结束”,而是“使用类似
SetThreadExecutionState()
和ES_DISPLAY_REQUIRED
阻止屏幕保护程序运行。并显示全屏显示当前状态的最顶部窗口,当您想要提醒用户时,可以闪烁引人注目的图形和/或播放声音来引起他们的注意”。虽然需要做更多的工作,这样做将解决设置“恢复时显示登录屏幕”的安全桌面的问题,并且还可以防止系统进入睡眠状态(如果配置为这样做)。 它通常只是允许应用程序更清楚地传达其意图。
除此之外,屏幕保护程序的显示以及如何阻止或中断它本质上是一项特定于操作的工作。 Linux 和 MacOS 需要不同的技术来与系统交互。
One way to interrupt a screen save programmatically is to move the mouse cursor. On Windows, however, that's not as simple as it might first seem.
The Windows operating system has a hierarchy of objects. At the top of the hierarchy is the "Window Station". Just below that is the "Desktop" (not to be confused with the desktop folder, or even the desktop window showing the icons of that folder). You can read more about this concept in the documentation.
I mention this because ordinarily only one Desktop can receive and process user input at any given time. And, when a screen saver is activated by Windows due to a timeout, Windows creates a new Desktop to run the screen saver.
This means any application associated with any other Desktop, including the running program you've written, will be unable to send input to the new Desktop without some extra work. The nature of that work depends on a few factors. Assuming the simplest case, a screen saver that's created without the "On resume, display logon screen", and no other Window Station has been created by a remote connection or local user login, then you can ask Windows for the active Desktop, attach the Python script to that Desktop, move the mouse, and revert back to the previous Desktop so the rest of the script works as expected.
Thankfully, the code to do this is easier than the explanation:
However, if the screen saver is running on a separate Window Station because "On resume, display logon screen" is selected, or another user is connected either via the physical Console or has connected remotely, then connecting to and attaching to the active Desktop will require elevation of the program, and even then, depending on other factors, it may require special permissions.
And while this might work for a given use case, I will add the the core issue in the general case is perhaps more properly defined as asking "how do I notify the user of the state of something, without the screen saver blocking that notification?". The answer to that question isn't "cause the screen saver to end", but rather "Use something like
SetThreadExecutionState()
withES_DISPLAY_REQUIRED
to keep the screen saver from running. And show a full-screen top-most window that shows the current status, and when you want to alert the user, flash an eye-catching graphic and/or play a sound to get their attention".While more work, doing that will solve issues around the secure desktop with "On resume, display logon screen" set, and also prevent the system from going to sleep if it's configured to do so. It just generally allows the application to more clearly communicate its intention.
And on top of this, the display of a screen saver and how to prevent it or interrupt it is inherently an operating specific endeavor. Linux and MacOS will require a different technique to interact with the system.