“无法使用已与其基础RCW分离的COM对象。”使用静态WMI事件

时间:2016-11-30 13:15:30

标签: c# static com wmi

我正在尝试实现具有静态事件的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()方法? 或者有没有办法捕捉和吞下这个例外? (正如关闭时一样,无论如何都可以忽略它)

0 个答案:

没有答案