2009-12-29 23 views
3

我已經看到了一些關於如何從Windows API使用RegisterDeviceNotification的例子,但是我還沒有看到任何.NET例子。我想編寫一個C#應用程序,它會在出現新驅動器時通知(特別是通過USB,火線等)。這個應用程序需要是Windows服務,所以我不能使用WM_DEVICECHANGE消息,沒有一些不良行爲的黑客入侵。我想避免這種情況。任何人都可以給我一個如何在C#中使用RegisterDeviceNotification的示例,或者至少給我一個很好的替代方案嗎?在.NET應用中使用RegisterDeviceNotification

編輯:再次,這是一個Windows 服務有沒有圖形用戶界面。因此涉及WM通知消息的possible duplicate在這種情況下不起作用。

+0

可能重複[檢查設備更改(添加/刪除)事件](http://stackoverflow.com/questions/16245706/check-for-device-change-add-remove-events) – 2017-03-28 15:43:02

+0

@ErwinMayer不可以。請參閱編輯。 – Phil 2017-03-29 00:49:15

回答

3
+0

該鏈接已經死亡 - 考慮找回+添加摘要或找到問題的重複。有類似的一個http://stackoverflow.com/questions/1783657/get-notification-when-a-new-drive-is-connected-via-usb-or-other-means-c?rq=1(沒有高質量答案) – 2016-02-18 08:05:59

0

This answer提供相關代碼樣本,以檢測USB設備移除或添加:從Windows

protected override void OnSourceInitialized(EventArgs e) 
    { 
     base.OnSourceInitialized(e); 

     // Adds the windows message processing hook and registers USB device add/removal notification. 
     HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle); 
     if (source != null) 
     { 
      windowHandle = source.Handle; 
      source.AddHook(HwndHandler); 
      UsbNotification.RegisterUsbDeviceNotification(windowHandle); 
     } 
    } 

    /// <summary> 
    /// Method that receives window messages. 
    /// </summary> 
    private IntPtr HwndHandler(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam, ref bool handled) 
    { 
     if (msg == UsbNotification.WmDevicechange) 
     { 
      switch ((int)wparam) 
      { 
       case UsbNotification.DbtDeviceremovecomplete: 
        Usb_DeviceRemoved(); // this is where you do your magic 
        break; 
       case UsbNotification.DbtDevicearrival: 
        Usb_DeviceAdded(); // this is where you do your magic 
        break; 
      } 
     } 

     handled = false; 
     return IntPtr.Zero; 
    } 

用法:

using System; 
using System.Runtime.InteropServices; 

internal static class UsbNotification 
{ 
    public const int DbtDevicearrival = 0x8000; // system detected a new device   
    public const int DbtDeviceremovecomplete = 0x8004; // device is gone  
    public const int WmDevicechange = 0x0219; // device change event  
    private const int DbtDevtypDeviceinterface = 5; 
    private static readonly Guid GuidDevinterfaceUSBDevice = new Guid("A5DCBF10-6530-11D2-901F-00C04FB951ED"); // USB devices 
    private static IntPtr notificationHandle; 

    /// <summary> 
    /// Registers a window to receive notifications when USB devices are plugged or unplugged. 
    /// </summary> 
    /// <param name="windowHandle">Handle to the window receiving notifications.</param> 
    public static void RegisterUsbDeviceNotification(IntPtr windowHandle) 
    { 
     DevBroadcastDeviceinterface dbi = new DevBroadcastDeviceinterface 
     { 
      DeviceType = DbtDevtypDeviceinterface, 
      Reserved = 0, 
      ClassGuid = GuidDevinterfaceUSBDevice, 
      Name = 0 
     }; 

     dbi.Size = Marshal.SizeOf(dbi); 
     IntPtr buffer = Marshal.AllocHGlobal(dbi.Size); 
     Marshal.StructureToPtr(dbi, buffer, true); 

     notificationHandle = RegisterDeviceNotification(windowHandle, buffer, 0); 
    } 

    /// <summary> 
    /// Unregisters the window for USB device notifications 
    /// </summary> 
    public static void UnregisterUsbDeviceNotification() 
    { 
     UnregisterDeviceNotification(notificationHandle); 
    } 

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    private static extern IntPtr RegisterDeviceNotification(IntPtr recipient, IntPtr notificationFilter, int flags); 

    [DllImport("user32.dll")] 
    private static extern bool UnregisterDeviceNotification(IntPtr handle); 

    [StructLayout(LayoutKind.Sequential)] 
    private struct DevBroadcastDeviceinterface 
    { 
     internal int Size; 
     internal int DeviceType; 
     internal int Reserved; 
     internal Guid ClassGuid; 
     internal short Name; 
    } 
} 

從一個WPF窗口用法表格:

public Form1() 
{ 
    InitializeComponent(); 
    UsbNotification.RegisterUsbDeviceNotification(this.Handle); 
} 

protected override void WndProc(ref Message m) 
{ 
    base.WndProc(ref m); 
     if (m.Msg == UsbNotification.WmDevicechange) 
    { 
     switch ((int)m.WParam) 
     { 
      case UsbNotification.DbtDeviceremovecomplete: 
       Usb_DeviceRemoved(); // this is where you do your magic 
       break; 
      case UsbNotification.DbtDevicearrival: 
       Usb_DeviceAdded(); // this is where you do your magic 
       break; 
     } 
    } 
}