Win32_DeviceChangeEvent сообщает только тип произошедшего события и время события (uint64, представляющее интервалы в 100 наносекунд после 1 января 1601 года, UTC). Не так уж и полезно, если вы также хотите знать, что прибыло или было удалено.
Я предлагаю вместо этого использовать класс WqlEventQuery , установив для EventClassName
значение __InstanceOperationEvent
.
Этот системный класс предоставляет свойство TargetInstance
, которое можно привести к ManagementBaseObject , полному объекту управления, который также предоставляет базовую информацию об устройстве, сгенерировавшем событие.
Среди этой информации (которая включает понятное имя устройства), PNPDeviceID
, которая может использоваться для создания других запросов для дальнейшей проверки устройства, на которое ссылаются.
Свойство WqlEventQuery
Condition можно установить здесь TargetInstance ISA 'Win32_DiskDrive'
.
Можно установить любой другой класс Win32_
.
Настройка прослушивателя событий (локальный компьютер):
(Обработчик события называется DeviceChangedEvent
)
WqlEventQuery query = new WqlEventQuery() {
EventClassName = "__InstanceOperationEvent",
WithinInterval = new TimeSpan(0, 0, 3),
Condition = @"TargetInstance ISA 'Win32_DiskDrive'"
};
ManagementScope scope = new ManagementScope("root\\CIMV2");
using (ManagementEventWatcher MOWatcher = new ManagementEventWatcher(scope, query))
{
MOWatcher.Options.Timeout = ManagementOptions.InfiniteTimeout;
MOWatcher.EventArrived += new EventArrivedEventHandler(DeviceChangedEvent);
MOWatcher.Start();
}
Обработчик события получает в e.NewEvent.Properties["TargetInstance"]
объект управления, представляющий класс Win32_DiskDrive .
Смотрите Документы о свойствах, прямо доступных здесь.
Интересующие производные классы __InstanceOperationEvent
, сообщаемые e.NewEvent.ClassPath.ClassName
, могут быть:
__ InstanceCreationEvent : Обнаружено прибытие нового устройства.
__ InstanceDeletionEvent : Обнаружено удаление устройства.
__ InstanceModificationEvent : Существующее устройство было каким-то образом модифицировано.
Обратите внимание, что событие возникает во вторичном потоке, нам нужно BeginInvoke
поток пользовательского интерфейса, чтобы обновить пользовательский интерфейс с новой информацией.
См. Здесь: Получите серийный номер запоминающего устройства USB для класса, который предоставляет большую часть информации, доступной об устройстве (информация фильтруется, чтобы показать только устройства USB, но фильтр можно удалить) ,
private void DeviceChangedEvent(object sender, EventArrivedEventArgs e)
{
using (ManagementBaseObject MOBbase = (ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value)
{
string oInterfaceType = MOBbase?.Properties["InterfaceType"]?.Value.ToString();
string devicePNPId = MOBbase?.Properties["PNPDeviceID"]?.Value.ToString();
string deviceDescription = MOBbase?.Properties["Caption"]?.Value.ToString();
string EventMessage = $"{oInterfaceType}: {deviceDescription} ";
switch (e.NewEvent.ClassPath.ClassName)
{
case "__InstanceDeletionEvent":
EventMessage += " removed";
this.BeginInvoke(new MethodInvoker(() => { this.UpdateUI(EventMessage); }));
break;
case "__InstanceCreationEvent":
EventMessage += "inserted";
this.BeginInvoke(new MethodInvoker(() => { this.UpdateUI(EventMessage); }));
break;
case "__InstanceModificationEvent":
default:
Console.WriteLine(e.NewEvent.ClassPath.ClassName);
break;
}
}
}
private void UpdateUI(string message)
{
//Update the UI controls with the updated informations
}