Ищете руководство по поиску ловушки в Win7, чтобы определить, подключен или отключен монитор - PullRequest
0 голосов
/ 27 марта 2019

Распределите большое количество видеоустройств Win7 в нескольких разных местах в медицинских учреждениях. Иногда потребность острая, и они могут быть использованы в кратчайшие сроки. Каждое устройство подключается через HDMI к настенному телевизору. Одна из проблем заключается в том, что иногда люди отсоединяют кабель HDMI от компьютера Win7, чтобы подключить свои собственные персональные устройства, что нарушает политику. Они не будут повторно подключать кабель, что вызывает проблемы, когда устройство необходимо использовать в следующий раз. Это вызвало задержки в уходе. На прошлой неделе я работал над созданием небольшого приложения (предпочтительно службы на системном уровне), которое будет определять, когда дисплей больше не подключен к ПК, а затем запускать действия (например, запись в EventLog, отправлять оповещения по электронной почте и т. Д.). К сожалению, все мои попытки были встречены контрольно-пропускными пунктами. Ищу идеи.

Я потратил довольно много времени на изучение способов или «ловушек», которые я мог бы обнаружить в Windows, с которых я могу сработать. Я обнаружил, что есть собственные классы (DeviceWatcher, WindowsDeviceEnumeration и т. Д.), Которые могут помочь этой работе, но, к сожалению, они не совместимы с Win7.
Я создал консольное приложение c # с обработчиком событий для SystemEvents.DisplaySettingsChanging, и это работает так, как мне бы хотелось! Я могу отключить монитор, и он отправит оповещение по электронной почте и запишет запись в журнал событий (который мы можем отслеживать с помощью сторонних инструментов и оповещений, создания тикетов и т. Д.). Хотя это консольное приложение прекрасно работает, мне нужно, чтобы оно больше работало как скрытый фоновый сервис. Я создал службу Windows с той же функциональностью, но обнаружил, что обработчики событий могут быть хитрыми в службах Windows. Я никогда не мог заставить EventHandler (SystemEvents_DisplaySettingsChanging) срабатывать в режиме обслуживания Windows. С тех пор я обнаружил, что EventHandler DisplaySettingsChanged является событием уровня пользователя и будет работать только для текущего пользователя, а не на уровне системы при запуске в качестве службы.
Я протестировал различные методы отключения монитора и поиска способов, чтобы окна сообщали «Нет монитора». Я попробовал класс WIn32_PnPEntity, а также классы Win32_Video *, и все они сообщат, что монитор в хорошем состоянии, даже если это не так. подключен.

Я обнаружил, что могу буквально наблюдать за диспетчером устройств при отключении монитора и видеть, как монитор исчезает из вкладки Мониторы. Должен быть какой-то способ, которым я могу зацепиться за это.
Я думаю, что могу запустить службу Windows с таймером, который проверит этот хук. Если монитор подключен, ничего не делайте - если НЕ подключен, выполните действие (отправьте предупреждение, запишите запись в журнал событий, создайте заявку и т. Д.)

В конечном итоге я ожидаю, что у меня будет служба Windows с таймером, которая будет работать в системном режиме, который в основном повторно запускает проверку следующим образом: Если монитор подключен, ничего не делать.
Если монитор не подключен, отправьте уведомление, создайте заявку, создайте запись в журнале событий и т. Д.

Я потратил на это немало времени и должен представить результаты 3/28.

Любая помощь приветствуется. Спасибо!

1 Ответ

0 голосов
/ 28 марта 2019

Я исследовал WM_DEVICECHANGE и WM_DISPLAYCHANGE, но я просто не мог заставить их работать так, как мне было нужно, и у меня не хватало времени.
Мне нужно больше времени, чтобы выяснить это (и захватить сообщения Windows в целом) вбудущее.
Однако я наконец-то смог найти правильный крюк для достижения своей цели.

Проблема, с которой я столкнулся, заключалась в том, что независимо от того, какой класс или сборку я использовал для обнаружения подключения монитора, я всегда былвозврат хотя бы одного дисплея, даже если он был физически отключен.

Работая в PowerShell, я обнаружил, что, используя WMI и Win32_PnPEntity, я могу получить информацию о дисплее, и если НЕТ дисплеи были подключены, DeviceID всегда будет возвращать Display \ NVD0000 \ SomeGuid.Когда подключены 1 или 2 монитора, DeviceID будет шестнадцатеричным вариантом, заменяющим нули после NVD (например, Display \ NVD39E4 \ someGUID).

Зная, что могу рассчитывать на получение идентификатора устройства Display \ NVD0000, когда монитор не был подключен, я создаю службу Windows с таймером, используя ManagementObjectSearcher и Win32_PnPEntity.Таймер запускается каждые 10 минут, а затем выполняет проверку.
Если физически подключенный дисплей не обнаружен, он запустит запись в журнале событий, мониторинг которой можно выполнить с помощью внешнего инструмента мониторинга (Xymon, Nagios и т. Д.), И предупреждение / действие может бытьприняты, чтобы убедиться, что это исправлено.

Я тестировал с монитором HDMI.Протестировано с монитором в состоянии выключенного питания и с изменением источника монитора на другое состояние входа (не HDMI), и единственное условие, при котором я мог активировать оповещение, было, когда кабель был физически отключен от ПК, что именно то, что я хотел.

Существует более одного способа кожи кошки.Я знаю, что есть другие разработчики, которые могли бы создать сложное рабочее решение за считанные минуты.Учитывая количество накопленного времени на экране в C # за всю мою карьеру (сравнительно немного), я рад этой маленькой победе.

Надеюсь, это может кому-то помочь в будущем.

...