寻找有关在Win7中定位挂钩的指南,以确定监视器是否已连接

时间:2019-03-27 02:46:48

标签: c# powershell winapi monitoring

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

我花了很多时间研究可能在Windows中浮出水面的方式或“陷阱”。我发现有些本机类(DeviceWatcher,WindowsDeviceEnumeration等)可能会帮助完成这项工作,但不幸的是它们与Win7不兼容。
我确实使用SystemEvents.DisplaySettingsChanging的事件处理程序创建了一个c#控制台应用程序,并且它的运行方式与我想要的一样!我可以断开监视器的连接,它将发送警报电子邮件并编写事件日志条目(我们可以使用第三方工具进行监视和警报,创建故障单等)。尽管此控制台应用程序运行良好,但我需要它作为隐藏的后台服务才能发挥更大的作用。我创建了具有相同功能的Windows服务,但是我发现事件处理程序在Windows服务中可能很棘手。在Windows服务模式下,我永远无法触发EventHandler(SystemEvents_DisplaySettingsChanging)。从那以后,我发现EventHandler DisplaySettingsChanged是用户级别的事件,当作为服务运行时,仅适用于当前用户,不适用于系统级别。
我已经测试了各种方法来断开监视器的连接,并寻找Windows报告“无监视器”的方法。我已经尝试了WIn32_PnPEntity类以及Win32_Video *类,它们都将报告监视器处于OK状态,即使它不是

我确实发现,在断开监视器的连接时,我确实可以观看设备管理器,并且该监视器从“监视器”选项卡中消失了。我必须有某种方法可以了解这一点。
我在想我可以运行带有计时器的Windows服务,该计时器将检查此钩子。如果已连接监视器,则什么都不做-如果未连接监视器,请执行操作(发送警报,写事件日志条目,创建票证等)

最终,我希望有一个带有计时器的Windows服务,它将在系统模式下运行,该模式基本上会重新运行如下检查: 如果连接了监视器,则什么也不做。
如果未连接任何监视器,请发送警报,创建故障单,创建事件日志条目等。

我在此上花了很多时间,我必须介绍发现结果3/28。

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

1 个答案:

答案 0 :(得分:0)

我浏览了WM_DEVICECHANGE和WM_DISPLAYCHANGE,但是我都无法按需工作,而且时间已经用完了。
我需要更多时间来解决这些问题(并通常捕获Windows消息)。
但是,我终于能够找到实现目标的正确方法。

我面临的挑战是,无论我用来检测监视器连接的是哪种类或程序集,即使物理断开连接,我始终会至少返回一个显示器。

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

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

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

有多种方法可以给猫做皮毛。我知道还有其他开发人员可以在几分钟之内完成精心设计的工作解决方案。考虑到我的职业生涯中C#的累计放映时间(相对而言不是很多),我对这次小小的胜利感到很好。

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