关于SD卡插入SD卡读卡器的VolumeChangeEvent的WMI查询无效

时间:2017-05-24 12:54:44

标签: .net wmi-query

我正在开发一个应用程序,我希望在SD卡插入SD卡读卡器时自动处理数据。 SD卡读卡器已插入计算机并分配了E:和F:驱动器,并且在未插入SD卡时显示为灰色。我一直在尝试使用基于Win32__VolumeChangeEvent或Win32__DeviceChangeEvent的WMI查询,但没有成功。我得到的错误"从Win32_VolumeChangeEvent"中选择*是无效的类,"从Win32_DeviceChangeEvent"中选择*我将SD卡插入SD卡读卡器时,不会显示状态更新,仅用于插入和取出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"));
        }
    }
}

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

1 个答案:

答案 0 :(得分:2)

以下代码是我的问题的有效解决方案,当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");
        }
    }
}