Rilevamento dell’inserimento e della rimozione delle unità USB tramite il servizio Windows e C #

Esaminare la possibilità di creare un’applicazione distribuita USB
che si avvierà automaticamente all’inserimento di una chiavetta USB e all’arresto quando si rimuove la levetta

Utilizzerà .Net e C #.
Alla ricerca di suggerimenti su come affrontare questo utilizzando C #?


Aggiornamento: due possibili soluzioni che implementano questo come servizio.
– ignora WndProc
o
– utilizzando la query WMI con ManagementEventWatcher

È ansible utilizzare WMI, è facile e funziona molto meglio della soluzione WndProc con servizi.

Qui c’è un semplice esempio:

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(); 

E questo è tutto 🙂

Questo funziona bene per me, in più puoi trovare ulteriori informazioni sul dispositivo.

 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); } 

Aggiunta al post di VitalyB.

Per generare un evento in cui è stato inserito QUALSIASI dispositivo USB, utilizzare quanto segue:

 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(); 

Ciò solleverà un evento ogni volta che viene collegato un dispositivo USB. Funziona anche con un DAQ di National Instruments che sto cercando di rilevare automaticamente.

La risposta di VitalyB non copre la rimozione del dispositivo. L’ho modificato un po ‘per triggersre l’evento sia quando il supporto è inserito sia rimosso e anche il codice per ottenere la lettera di unità del supporto inserito.

 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(); } } } 

È inoltre ansible utilizzare WMI per rilevare eventi di inserimento. È un po ‘più complicato del monitoraggio dei messaggi WM_CHANGEDEVICE, ma non richiede un handle di finestra che può essere utile se si esegue in background come servizio.

Prova la gestione di WM_CHANGEDEVICE .

Ecco cosa abbiamo fatto con C # .Net 4.0 in un’app WPF. Stiamo ancora cercando una risposta a “come dire che tipo di dispositivo è stato inserito / rimosso”, ma questo è un inizio:

  using System.Windows.Interop; ... public partial class MainWindow : Window { ... public MainWindow() { ... } //============================================================ // WINDOWS MESSAGE HANDLERS // private const int WM_DEVICECHANGE = 0x0219; // int = 537 private const int DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 0x00000004; ///  /// ///  ///  protected override void OnSourceInitialized(EventArgs e) { base.OnSourceInitialized(e); HwndSource source = PresentationSource.FromVisual(this) as HwndSource; source.AddHook(WndProc); } private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { if (msg == WM_DEVICECHANGE) { ReadDongleHeader(); } return IntPtr.Zero; } } 

Un po ‘di modifica su tutte le risposte precedenti:

 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(); } }