Link to home
Start Free TrialLog in
Avatar of dcrudo
dcrudo

asked on

How to Monitor if a USB device is plugged in?

Dear Experts,

I would like to create a service in Delphi that monitors every few seconds if a USB device (USB Drive) has been plugged in...  but not relaying on the drive letter...but maybe on the device serial number or device name.

Is there any function in delphi 2005 that can do this?

Thank you!

Dave.
Avatar of Johnjces
Johnjces
Flag of United States of America image

Hello.

I did the same thing with D7 making a service. I am at work and the code and component I am thinking of is at home but I am pretty sure it was the JvHIDDeviceController component in the Jv library. I "think" it (JvLib) is upgraded for 2005.

You can donwload the JVCL and JbLibs form Sourceforge.net.

I will advise for sure tonight when I get home, but that component checks for most any USB being inserted and removed. (used it to "gong" my 2000 box at home like my XP box does at work).

I can post my "rough" code for the service as well but 9 hours from now.

JOhn J
Avatar of dcrudo
dcrudo

ASKER

No problem ;)

No hurry!

Thx a lot!
ASKER CERTIFIED SOLUTION
Avatar of ginsonic
ginsonic
Flag of Romania image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Just use WMDEVICECHANGE message in your service.
listening...
Have a look at http://www.sf.net/projects/jedi-apilib
Get the modules win32api and scapi. scapi contains some examples which should solve most of your problem.
Be advised that especially the function CM_Request_Device_Eject is problematic in a service. It can produce a delay of 30 secs and more.
For detailed help please ask me directly. My email is enclosed in the units.
Hi!
You can try this compoent...

(* original code by Miguel Lucero *)

/////////////////////////// begin code ///////////////////////////

// Component to detect when usb devices are connected or disconnected
// using RegisterDeviceNotification

unit U_Usb;

interface

uses
  Windows, Messages, SysUtils, Classes, Forms;

type

    PDevBroadcastHdr = ^DEV_BROADCAST_HDR;
    DEV_BROADCAST_HDR = packed record
      dbch_size: DWORD;
      dbch_devicetype: DWORD;
      dbch_reserved: DWORD;
    end;

    PDevBroadcastDeviceInterface = ^DEV_BROADCAST_DEVICEINTERFACE;
    DEV_BROADCAST_DEVICEINTERFACE = record
      dbcc_size: DWORD;
      dbcc_devicetype: DWORD;
      dbcc_reserved: DWORD;
      dbcc_classguid: TGUID;
      dbcc_name: short;
    end;

const
     GUID_DEVINTERFACE_USB_DEVICE: TGUID = '{A5DCBF10-6530-11D2-901F-00C04FB951ED}';
     DBT_DEVICEARRIVAL            = $8000;          // system detected a new device
     DBT_DEVICEREMOVECOMPLETE     = $8004;          // device is gone
     DBT_DEVTYP_DEVICEINTERFACE   = $00000005;      // device interface class

type

  TComponentUSB = class(TComponent)
  private
    FWindowHandle: HWND;
    FOnUSBArrival: TNotifyEvent;
    FOnUSBRemove: TNotifyEvent;
    procedure WndProc(var Msg: TMessage);
    function USBRegister: Boolean;
  protected
    procedure WMDeviceChange(var Msg : TMessage); dynamic;
  public
    constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;
  published
    property OnUSBArrival: TNotifyEvent read FOnUSBArrival write FOnUSBArrival;
    property OnUSBRemove: TNotifyEvent read FOnUSBRemove write FOnUSBRemove;
  end;

implementation

constructor TComponentUSB.Create(AOwner : TComponent);
begin
     inherited Create(AOwner);
     FWindowHandle := AllocateHWnd(WndProc);
     USBRegister;
end;

destructor TComponentUSB.Destroy;
begin
     DeallocateHWnd(FWindowHandle);
     inherited Destroy;
end;

procedure TComponentUSB.WndProc(var Msg: TMessage);
begin
     if (Msg.Msg = WM_DEVICECHANGE) then begin
        try
           WMDeviceChange( Msg );
        except
              Application.HandleException(Self);
        end;
     end
     else
         Msg.Result := DefWindowProc( FWindowHandle, Msg.Msg, Msg.wParam, Msg.lParam);
end;

procedure TComponentUSB.WMDeviceChange(var Msg : TMessage);
var
   devType: Integer;
   Datos: PDevBroadcastHdr;
begin
     if (msg.WParam=DBT_DEVICEARRIVAL) or (msg.WParam=DBT_DEVICEREMOVECOMPLETE) then begin
        Datos := PDevBroadcastHdr(msg.LParam);
        devType := Datos^.dbch_devicetype;
        if devType=DBT_DEVTYP_DEVICEINTERFACE then begin // USB Device
           if msg.WParam=DBT_DEVICEARRIVAL then begin
              if Assigned( FOnUSBArrival ) then
                 FOnUSBArrival( Self );
           end else begin
               if Assigned( FOnUSBRemove ) then
                  FOnUSBRemove( Self );
           end;
        end;
     end;
end;

function TComponentUSB.USBRegister: Boolean;
var
   dbi: DEV_BROADCAST_DEVICEINTERFACE;
   size: Integer;
   r: Pointer;
begin
     Result := False;
     size := SizeOf(DEV_BROADCAST_DEVICEINTERFACE);
     ZeroMemory( @dbi, size );
     dbi.dbcc_size := size;
     dbi.dbcc_devicetype := DBT_DEVTYP_DEVICEINTERFACE;
     dbi.dbcc_reserved := 0;
     dbi.dbcc_classguid := GUID_DEVINTERFACE_USB_DEVICE;
     dbi.dbcc_name := 0;

     r := RegisterDeviceNotification( FWindowHandle,
                                      @dbi,
                                      DEVICE_NOTIFY_WINDOW_HANDLE
                                     );
     if Assigned( r ) then Result := True;

end;

end.

//////////////////////////// end code ////////////////////////////

Good Luck!