1

Я пытаюсь запустить приложение, когда добавлено специальное USB-устройство.

В системе событий Windows я могу использовать событие: Microsoft-Windows-DriverFrameworks-UserMode -> Код Event ID: 2100

Это событие возникает при добавлении нового устройства. Это работает нормально, но я выясню, какой диск был добавлен.

В системе событий, которую я обнаружил, эта дополнительная информация доступна, но как я могу использовать эту информацию?

Можно ли получить информацию, какой диск был добавлен? Или можно передать дополнительные данные системы событий пользовательской программе (параметр командной строки)?

1 ответ1

3

Я не знаю, как вы могли бы сделать это без программирования, но я написал приложения, которые делают именно то, что вы хотите. Вот как это реализовать.

Когда в систему добавляется новое устройство (например, 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 ) );
    }
  }
}

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .