【问题标题】:WMI query on VolumeChangeEvent for SD card insertion into SD card reader not working针对将 SD 卡插入 SD 卡读卡器的 VolumeChangeEvent 的 WMI 查询不起作用
【发布时间】:2017-05-24 12:54:44
【问题描述】:

我正在开发一个应用程序,我希望在将 SD 卡插入 SD 卡读卡器时自动处理来自 SD 卡的数据。 SD卡读卡器插入电脑并分配E:和F:驱动器,当没有插入SD卡时显示为灰色。我一直在尝试使用基于 Win32__VolumeChangeEvent 或 Win32__DeviceChangeEvent 的 WMI 查询,但没有成功。我收到的“select * from Win32_VolumeChangeEvent”错误是无效类,当我将 SD 卡插入 SD 卡读卡器时,“select * from Win32_DeviceChangeEvent”不显示状态更新,仅用于插入和移除 SD读卡器本身。

我用来实验的一个类是:

 namespace eventTest
{
    class WMIReceiveEvent
    {
        static void Main(string[] args)
        {
            WMIReceiveEvent receiveEvent = new WMIReceiveEvent();
            Console.Read();
        }

        public WMIReceiveEvent()
        {
            try
            {
                ManagementScope scope = new ManagementScope("root\\CIMV2");
                scope.Options.EnablePrivileges = true;
                WqlEventQuery query = new WqlEventQuery("select * from Win32_DeviceChangeEvent");
                ManagementEventWatcher watcher = new ManagementEventWatcher(scope, query);
                Console.WriteLine("Waiting for an event...");

                watcher.EventArrived += new EventArrivedEventHandler(HandleEvent);

                // Start listening for events
                watcher.Start();
            }
            catch (ManagementException err)
            {
                Console.WriteLine("An error occurred while trying to receive an event: " + err.Message);
            }
        }

        private void HandleEvent(object sender,
            EventArrivedEventArgs e)
        {
            Console.WriteLine(e.NewEvent.GetPropertyValue("EventType"));
        }
    }
}

任何人都可以向我们提供一个查询,我可以使用它来监控 Windows 中 SD 卡的到达,或者指出为什么 Win32_VolumeChangeEvent 不被接受为有效类,如果已修复,如何使用它来监控到达实际的 SD 卡?

【问题讨论】:

    标签: .net wmi-query


    【解决方案1】:

    以下代码是解决我的问题的有效解决方案,当 SD 卡进入 USB 连接的 SD 读卡器时,我会收到通知。查询是

    SELECT * FROM __InstanceOperationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_LogicalDisk' and TargetInstance.Size > 0 AND TargetInstance.Description = "Removable disk"
    

    选择大小大于 0 且涉及可移动驱动器的逻辑磁盘上的所有操作。可以进一步区分操作类型(插入和移除)并检索插入的 SD 卡的驱动器号。 (例子见this stackoverflow question

    编辑:插入时触发的事件似乎是一个“__InstanceModificationEvent”,可以用来代替 __InstanceOperationEvent(__InstanceModificationEvent 是 __InstanceOperationEvent 的子类),在这种情况下查询是:

    SELECT * FROM __InstanceModificationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_LogicalDisk' and TargetInstance.Size > 0 AND TargetInstance.Description = "Removable disk"
    

    完整示例:

    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.IO;
    using System.Linq;
    using System.Management;
    using System.Threading;
    
    
    namespace eventTest
    {
        class WMIReceiveEvent
        {
            static void Main(string[] args)
            {
                WMIReceiveEvent receiveEvent = new WMIReceiveEvent();
                Console.Read();
            }
    
            public WMIReceiveEvent()
            {
                try
                {
                    ManagementScope scope = new ManagementScope("root\\CIMV2");
                    scope.Options.EnablePrivileges = true;
                    WqlEventQuery query = new WqlEventQuery("SELECT * FROM __InstanceModificationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_LogicalDisk' and TargetInstance.Size > 0 AND TargetInstance.Description = \"Removable disk\"");
                    ManagementEventWatcher watcher = new ManagementEventWatcher(scope, query);
                    Console.WriteLine("Waiting for an event...");
    
                    watcher.EventArrived += new EventArrivedEventHandler(HandleEvent);
    
                    // Start listening for events
                    watcher.Start();
                }
                catch (ManagementException err)
                {
                    Console.WriteLine("An error occurred while trying to receive an event: " + err.Message);
                }
            }
    
            private void HandleEvent(object sender,
                EventArrivedEventArgs e)
            {
                //ManagementBaseObject baseObject = (ManagementBaseObject)e.NewEvent;
    
               // if (baseObject.ClassPath.ClassName.Equals("__InstanceCreationEvent"))
                    Console.WriteLine("A drive was connected");
                //else if (baseObject.ClassPath.ClassName.Equals("__InstanceDeletionEvent"))
                    //Console.WriteLine("A drive was removed");
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      相关资源
      最近更新 更多