【问题标题】:Looking for guidance on locating hook in Win7 to determine if monitor is connected or disconnected寻找有关在 Win7 中定位挂钩以确定显示器是连接还是断开连接的指导
【发布时间】:2019-03-27 02:46:48
【问题描述】:

将大量 Win7 视频设备分布在医疗保健环境中的多个不同位置。有时需求很迫切,它们会在瞬间通知中使用。每个设备都通过 HDMI 连接到壁挂式电视。 一个痛点是,有时人们会从 Win7 计算机上断开 HDMI 电缆以插入自己的个人设备,这违反了政策。他们不会重新连接电缆,这会在下次需要使用设备时导致问题。这导致护理延误。 过去一周我一直在努力编写一个小应用程序(最好是系统级别的服务),它将检测显示器何时不再连接到 PC 然后触发操作(例如 EventLog 条目、发送电子邮件警报等)。不幸的是,我所有的尝试都遇到了障碍。寻找想法。

我花了很多时间研究我可以在 Windows 中触发的方法或“钩子”。我发现有本地类(DeviceWatcher、WindowsDeviceEnumeration 等)可能有助于这项工作,但不幸的是它们与 Win7 不兼容。
我确实为 SystemEvents.DisplaySettingsChanging 创建了一个带有事件处理程序的 c# 控制台应用程序,这正是我想要的!我可以断开监视器,它会发送一封警报电子邮件并编写一个事件日志条目(我们可以使用 3rd 方工具和警报进行监控,创建票证等)。虽然这个控制台应用程序运行良好,但我需要它更多地作为隐藏的后台服务工作。我创建了一个具有相同功能的 Windows 服务,但我发现 Windows 服务中的事件处理程序可能很棘手。在 Windows 服务模式下,我永远无法触发 EventHandler(SystemEvents_DisplaySettingsChanging)。从那以后,我发现 EventHandler DisplaySettingsChanged 是一个用户级别的事件,并且在作为服务运行时仅适用于当前用户而不是系统级别。
我已经测试了各种拔下显示器的方法并寻找 Windows 报告“无显示器”的方法。我已经尝试过 WIn32_PnPEntity 类以及 Win32_Video* 类,它们都会报告显示器状态正常,即使它不是已连接。

我确实发现我可以在断开显示器连接时真正观看设备管理器,然后看到显示器从“显示器”选项卡中消失。必须有某种方法可以吸引我。
我在想我可以运行一个带有计时器的 Windows 服务来检查这个钩子。如果监视器已连接,则不执行任何操作 - 如果未连接,则执行操作(发送警报、写入事件日志条目、创建票证等)

最终我希望有一个带有计时器的 Windows 服务,它将在系统模式下运行,基本上重新运行这样的检查: 如果显示器已连接,则什么也不做。
如果没有连接监视器,则发送警报、创建票证、创建事件日志条目等。

我在这方面花了很多时间,我必须在 3/28 上展示调查结果。

任何帮助表示赞赏。谢谢!

【问题讨论】:

  • 在搜索引擎中对 wm_devicechange hdmi 进行快速搜索,发现了一些看起来很有希望的结果。

标签: c# powershell winapi monitoring


【解决方案1】:

我探索了 WM_DEVICECHANGE 和 WM_DISPLAYCHANGE,但我都无法根据需要工作,而且我的时间不多了。
我需要更多时间来解决这些问题(并在一般情况下捕获 Windows 消息)。
不过,我终于找到了实现目标的正确方法。

我遇到的挑战是,无论我使用什么类或程序集来检测显示器连接,我总是返回至少一个显示器,即使它在物理上已断开连接。

在 PowerShell 中修修补补,我发现使用 WMI 和 Win32_PnPEntity,我可以提取显示信息,如果未连接任何显示器,则 DeviceID 将始终返回 Display\NVD0000\SomeGuid。当连接 1 或 2 台显示器时,DeviceID 将是一个十六进制变量,替换 NVD 之后的零(例如 Display\NVD39E4\someGUID)。

知道当没有连接显示器时我可以指望获得 Display\NVD0000 的设备 ID,我构建了一个 Windows 服务,并使用 ManagementObjectSearcher 和 Win32_PnPEntity 设置了一个计时器。计时器每 10 分钟运行一次,然后执行检查。
如果发现没有物理连接的显示器,它将触发一个事件日志条目,该条目可以使用外部监控工具(Xymon、Nagios 等)进行监控,并且可以采取警报/操作以确保它得到纠正。

我使用 HDMI 显示器进行了测试。在关闭状态下的监视器和监视器源更改为另一个输入条件(不是 HDMI)的情况下进行测试,唯一可以触发警报的条件是电缆与 PC 物理断开时,这正是我想要的。

给猫剥皮的方法不止一种。我知道还有其他开发人员可以在几分钟内拼凑出一个精心设计的工作解决方案。考虑到在我的职业生涯中使用 C# 的累积屏幕时间量(相对而言不是很多),我对这个小小的胜利感觉很好。

希望这对将来的某人有所帮助。

【讨论】:

    猜你喜欢
    • 2013-12-31
    • 1970-01-01
    • 2015-04-19
    • 2020-03-23
    • 1970-01-01
    • 2016-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多