Inicia uma ação quando um dispositivo USB é adicionado [duplicado]

1

Eu tento iniciar um aplicativo quando um dispositivo USB especial é adicionado.

No sistema de eventos do Windows, posso usar o evento: Microsoft-Windows-DriverFrameworks-UserMode - > Event ID: 2100

Este evento é gerado quando um novo dispositivo é adicionado. Isso funciona bem, mas vou descobrir qual drive foi adicionado.

Dentro do sistema de eventos descobri que informações adicionais estão disponíveis, mas como posso usar essas informações?

É possível obter as informações, qual unidade foi adicionada? Ou é possível entregar os dados adicionais do sistema de eventos para um programa do usuário (parâmetro da linha de comando)?

    
por user263387 14.10.2013 / 13:40

1 resposta

3

Eu não sei como você poderia fazer isso sem programar, mas eu escrevi aplicativos que fazem exatamente o que você quer. Então, aqui está como implementá-lo.

Quando um novo dispositivo é adicionado ao sistema (como uma unidade USB), o Windows envia o WM_DEVICECHANGE mensagem para todas as janelas de aplicativo de nível superior. O evento a procurar é DBT_DEVICEARRIVAL (que é indicado através do wParam dessa mensagem).

O lParam da mensagem deve primeiro ser tratado como um DEV_BROADCAST_HDR . O cabeçalho indicará (através de dbch_devicetype member) se o dispositivo é realmente um volume ( DBT_DEVTYP_VOLUME ). Se for um volume, você pode reinterpretar o lParam da mensagem original como um DEV_BROADCAST_VOLUME . Essa estrutura indicará as letras de unidade atribuídas através do membro dbcv_unitmask .

Para torná-lo (espero) um pouco mais claro, aqui está um código de trabalho de uma implementação da minha em 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 ) );
    }
  }
}
    
por 14.10.2013 / 13:55

Tags