我正在尝试实现具有静态事件的USB设备通知程序,例如没有USB设备。我尝试使用类似以下的类:
public static class WmiUsbNotifier
{
private static ManagementEventWatcher watcherDetach;
public static event EventHandler<EventArgs<WmiDeviceNotifyEventArgs>> DeviceNotify;
public static void Initialize()
{
var detachQuery = new WqlEventQuery("SELECT * FROM __InstanceDeletionEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_USBControllerDevice'");
watcherDetach = new ManagementEventWatcher();
watcherDetach.EventArrived += ManagementEventWatcher_Detaching;
watcherDetach.Query = detachQuery;
watcherDetach.Start();
}
public static void ShutDown()
{
watcherDetach?.Stop();
watcherDetach?.Dispose();
watcherDetach = null;
}
private static void ManagementEventWatcher_Detaching(object sender, EventArrivedEventArgs e)
{
var targetInstance = (ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value;
var id = targetInstance.Properties["Dependent"].Value.ToString();
DeviceNotify?.Invoke(watcherDetach, new WmiDeviceNotifyEventArgs(EventType.DeviceRemoveComplete, id));
}
}
这很好用,一切都很好如果我在关闭我的应用之前调用ShutDown()
(例如在我的WPF应用的OnExit
中)。但是,如果我不打电话给我关闭我的应用程序时会出现以下错误:
System.Management.dll中出现未处理的“System.Runtime.InteropServices.InvalidComObjectException”类型异常
附加信息:无法使用已与其基础RCW分离的COM对象。
现在我想避免这种情况而不需要“外部调用ShutDown()”,因为这是其他人可以使用的库的一部分,很可能会忘记在他们的应用程序中调用该方法
我尝试在AppDomain.CurrentDomain.DomainUnload
中调用它,但在此之前发生异常。我也尝试使上面的类不是静态的,并添加一个终结器/ IDisposable并将一个实例设置为另一个类的静态属性,但终结器也被调用到很晚。
在此异常发生之前,有没有办法自动调用ShutDown()
方法?
或者有没有办法捕捉和吞下这个例外? (正如关闭时一样,无论如何都可以忽略它)