研究制作USB分布式应用程序的可能性,该应用程序
将在插入USB记忆棒时自动启动并在移除记忆棒时关闭
将使用.Net和C#.
寻找建议如何使用C#解决这个问题?
您可以使用WMI,它很容易,并且它比WndProc解决方案的服务更好.
这是一个简单的例子:
using System.Management; ManagementEventWatcher watcher = new ManagementEventWatcher(); WqlEventQuery query = new WqlEventQuery("SELECT * FROM Win32_VolumeChangeEvent WHERE EventType = 2"); watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived); watcher.Query = query; watcher.Start(); watcher.WaitForNextEvent();
就是这样:)
这对我很有用,您还可以找到有关该设备的更多信息.
using System.Management; private void DeviceInsertedEvent(object sender, EventArrivedEventArgs e) { ManagementBaseObject instance = (ManagementBaseObject)e.NewEvent["TargetInstance"]; foreach (var property in instance.Properties) { Console.WriteLine(property.Name + " = " + property.Value); } } private void DeviceRemovedEvent(object sender, EventArrivedEventArgs e) { ManagementBaseObject instance = (ManagementBaseObject)e.NewEvent["TargetInstance"]; foreach (var property in instance.Properties) { Console.WriteLine(property.Name + " = " + property.Value); } } private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { WqlEventQuery insertQuery = new WqlEventQuery("SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_USBHub'"); ManagementEventWatcher insertWatcher = new ManagementEventWatcher(insertQuery); insertWatcher.EventArrived += new EventArrivedEventHandler(DeviceInsertedEvent); insertWatcher.Start(); WqlEventQuery removeQuery = new WqlEventQuery("SELECT * FROM __InstanceDeletionEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_USBHub'"); ManagementEventWatcher removeWatcher = new ManagementEventWatcher(removeQuery); removeWatcher.EventArrived += new EventArrivedEventHandler(DeviceRemovedEvent); removeWatcher.Start(); // Do something while waiting for events System.Threading.Thread.Sleep(20000000); }
添加到VitalyB的帖子.
要引发插入任何 USB设备的事件,请使用以下命令:
var watcher = new ManagementEventWatcher(); var query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2"); watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived); watcher.Query = query; watcher.Start();
无论何时插入USB设备,都会引发事件.它甚至可以与我试图自动检测的National Instruments DAQ一起使用.
VitalyB的答案不包括删除设备.我更改了一下,以便在插入和删除介质时触发事件,并且还编码以获取插入介质的驱动器号.
using System; using System.Management; namespace MonitorDrives { class Program { public enum EventType { Inserted = 2, Removed = 3 } static void Main(string[] args) { ManagementEventWatcher watcher = new ManagementEventWatcher(); WqlEventQuery query = new WqlEventQuery("SELECT * FROM Win32_VolumeChangeEvent WHERE EventType = 2 or EventType = 3"); watcher.EventArrived += (s, e) => { string driveName = e.NewEvent.Properties["DriveName"].Value.ToString(); EventType eventType = (EventType)(Convert.ToInt16(e.NewEvent.Properties["EventType"].Value)); string eventName = Enum.GetName(typeof(EventType), eventType); Console.WriteLine("{0}: {1} {2}", DateTime.Now, driveName, eventName); }; watcher.Query = query; watcher.Start(); Console.ReadKey(); } } }
以上所有答案都有点编辑:
using System.Management; public partial class MainForm : Form { public MainForm() { InitializeComponent(); bgwDriveDetector.DoWork += bgwDriveDetector_DoWork; bgwDriveDetector.RunWorkerAsync(); } private void DeviceInsertedEvent(object sender, EventArrivedEventArgs e) { string driveName = e.NewEvent.Properties["DriveName"].Value.ToString(); MessageBox.Show(driveName + " inserted"); } private void DeviceRemovedEvent(object sender, EventArrivedEventArgs e) { string driveName = e.NewEvent.Properties["DriveName"].Value.ToString(); MessageBox.Show(driveName + " removed"); } void bgwDriveDetector_DoWork(object sender, DoWorkEventArgs e) { var insertQuery = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2"); var insertWatcher = new ManagementEventWatcher(insertQuery); insertWatcher.EventArrived += DeviceInsertedEvent; insertWatcher.Start(); var removeQuery = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 3"); var removeWatcher = new ManagementEventWatcher(removeQuery); removeWatcher.EventArrived += DeviceRemovedEvent; removeWatcher.Start(); } }
您也可以使用WMI来检测插入事件。它比监视WM_CHANGEDEVICE消息要复杂一些,但是它不需要窗口句柄,如果在后台作为服务运行,则该窗口句柄可能很有用。