添加 USB 设备时启动操作

添加 USB 设备时启动操作

当添加特殊的 USB 设备时,我尝试启动一个应用程序。

在 Windows 事件系统中,我可以使用事件: Microsoft-Windows-DriverFrameworks-UserMode->Event ID: 2100

添加新设备时会引发此事件。这很好用,但我会找出添加了哪个驱动器。

我在事件系统中发现了附加信息,但我如何使用这些信息呢?

是否可以获取添加了哪个驱动器的信息?或者是否可以将事件系统的附加数据移交给用户程序(命令行参数)?

答案1

我不知道如何在不编程的情况下做到这一点,但我编写的应用程序可以完全满足您的要求。下面介绍如何实现它。

当新设备添加到系统(如 USB 驱动器)时,Windows 会发送WM_DEVICECHANGE消息发送到所有顶层应用程序窗口。要查找的事件是DBT_DEVICEARRIVAL(通过该消息的表明wParam)。

消息的应该lParam首先被视为DEV_BROADCAST_HDR。标头将指示(通过其dbch_devicetype成员)设备是否实际上是卷(DBT_DEVTYP_VOLUME)。如果是卷,您可以将lParam原始消息的重新解释为DEV_BROADCAST_VOLUME. 然后该结构将通过成员指示分配的驱动器号dbcv_unitmask

为了(希望)使其更清楚一些,下面是我在 C# 中实现的一些工作代码:

private static void MessageEventsMessageReceived( object sender, MessageReceivedEventArgs e ) {
  // Check if this is a notification regarding a new device.);
  if( e.Message.WParam == (IntPtr)NativeMethods.DBT_DEVICEARRIVAL ) {
    Log.Info( "New device has arrived" );

    // Retrieve the device broadcast header
    NativeMethods.DEV_BROADCAST_HDR deviceBroadcastHeader =
      (NativeMethods.DEV_BROADCAST_HDR)
      Marshal.PtrToStructure( e.Message.LParam, typeof( NativeMethods.DEV_BROADCAST_HDR ) );

    if( (int)NativeMethods.DBT_DEVTYP.DBT_DEVTYP_VOLUME == deviceBroadcastHeader.dbch_devicetype ) {
      Log.Info( "Device type is a volume (good)." );

      NativeMethods.DEV_BROADCAST_VOLUME volumeBroadcast =
        (NativeMethods.DEV_BROADCAST_VOLUME)
        Marshal.PtrToStructure( e.Message.LParam, typeof( NativeMethods.DEV_BROADCAST_VOLUME ) );

      Log.InfoFormat( "Unit masked for new device is: {0}", volumeBroadcast.dbcv_unitmask );

      int driveIndex = 1;
      int bitCount = 1;
      while( bitCount <= 0x2000000 ) {
        driveIndex++;
        bitCount *= 2;

        if( ( bitCount & volumeBroadcast.dbcv_unitmask ) != 0 ) {
          Log.InfoFormat( "Drive index {0} is set in unit mask.", driveIndex );
          Log.InfoFormat( "Device provides drive: {0}:", (char)( driveIndex + 64 ) );

          int index = driveIndex;
          char driveLetter = (char)( driveIndex + 64 );
          // Do something with driveLetter

        }
      }

    } else {
      Log.InfoFormat( "Device type is {0} (ignored).", Enum.GetName( typeof( NativeMethods.DBT_DEVTYP ), deviceBroadcastHeader.dbch_devicetype ) );
    }
  }
}

相关内容