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.
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.
ASKER
No problem ;)
No hurry!
Thx a lot!
No hurry!
Thx a lot!
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.
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;
PDevBroadcastDeviceInterfa ce = ^DEV_BROADCAST_DEVICEINTER FACE;
DEV_BROADCAST_DEVICEINTERF ACE = record
dbcc_size: DWORD;
dbcc_devicetype: DWORD;
dbcc_reserved: DWORD;
dbcc_classguid: TGUID;
dbcc_name: short;
end;
const
GUID_DEVINTERFACE_USB_DEVI CE: TGUID = '{A5DCBF10-6530-11D2-901F- 00C04FB951 ED}';
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(AOwne r : TComponent);
begin
inherited Create(AOwner);
FWindowHandle := AllocateHWnd(WndProc);
USBRegister;
end;
destructor TComponentUSB.Destroy;
begin
DeallocateHWnd(FWindowHand le);
inherited Destroy;
end;
procedure TComponentUSB.WndProc(var Msg: TMessage);
begin
if (Msg.Msg = WM_DEVICECHANGE) then begin
try
WMDeviceChange( Msg );
except
Application.HandleExceptio n(Self);
end;
end
else
Msg.Result := DefWindowProc( FWindowHandle, Msg.Msg, Msg.wParam, Msg.lParam);
end;
procedure TComponentUSB.WMDeviceChan ge(var Msg : TMessage);
var
devType: Integer;
Datos: PDevBroadcastHdr;
begin
if (msg.WParam=DBT_DEVICEARRI VAL) or (msg.WParam=DBT_DEVICEREMO VECOMPLETE ) then begin
Datos := PDevBroadcastHdr(msg.LPara m);
devType := Datos^.dbch_devicetype;
if devType=DBT_DEVTYP_DEVICEI NTERFACE then begin // USB Device
if msg.WParam=DBT_DEVICEARRIV AL 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_DEVICEINTERF ACE;
size: Integer;
r: Pointer;
begin
Result := False;
size := SizeOf(DEV_BROADCAST_DEVIC EINTERFACE );
ZeroMemory( @dbi, size );
dbi.dbcc_size := size;
dbi.dbcc_devicetype := DBT_DEVTYP_DEVICEINTERFACE ;
dbi.dbcc_reserved := 0;
dbi.dbcc_classguid := GUID_DEVINTERFACE_USB_DEVI CE;
dbi.dbcc_name := 0;
r := RegisterDeviceNotification ( FWindowHandle,
@dbi,
DEVICE_NOTIFY_WINDOW_HANDL E
);
if Assigned( r ) then Result := True;
end;
end.
////////////////////////// // end code ////////////////////////// //
Good Luck!
You can try this compoent...
(* original code by Miguel Lucero *)
//////////////////////////
// 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;
PDevBroadcastDeviceInterfa
DEV_BROADCAST_DEVICEINTERF
dbcc_size: DWORD;
dbcc_devicetype: DWORD;
dbcc_reserved: DWORD;
dbcc_classguid: TGUID;
dbcc_name: short;
end;
const
GUID_DEVINTERFACE_USB_DEVI
DBT_DEVICEARRIVAL = $8000; // system detected a new device
DBT_DEVICEREMOVECOMPLETE = $8004; // device is gone
DBT_DEVTYP_DEVICEINTERFACE
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(AOwne
begin
inherited Create(AOwner);
FWindowHandle := AllocateHWnd(WndProc);
USBRegister;
end;
destructor TComponentUSB.Destroy;
begin
DeallocateHWnd(FWindowHand
inherited Destroy;
end;
procedure TComponentUSB.WndProc(var Msg: TMessage);
begin
if (Msg.Msg = WM_DEVICECHANGE) then begin
try
WMDeviceChange( Msg );
except
Application.HandleExceptio
end;
end
else
Msg.Result := DefWindowProc( FWindowHandle, Msg.Msg, Msg.wParam, Msg.lParam);
end;
procedure TComponentUSB.WMDeviceChan
var
devType: Integer;
Datos: PDevBroadcastHdr;
begin
if (msg.WParam=DBT_DEVICEARRI
Datos := PDevBroadcastHdr(msg.LPara
devType := Datos^.dbch_devicetype;
if devType=DBT_DEVTYP_DEVICEI
if msg.WParam=DBT_DEVICEARRIV
if Assigned( FOnUSBArrival ) then
FOnUSBArrival( Self );
end else begin
if Assigned( FOnUSBRemove ) then
FOnUSBRemove( Self );
end;
end;
end;
end;
function TComponentUSB.USBRegister:
var
dbi: DEV_BROADCAST_DEVICEINTERF
size: Integer;
r: Pointer;
begin
Result := False;
size := SizeOf(DEV_BROADCAST_DEVIC
ZeroMemory( @dbi, size );
dbi.dbcc_size := size;
dbi.dbcc_devicetype := DBT_DEVTYP_DEVICEINTERFACE
dbi.dbcc_reserved := 0;
dbi.dbcc_classguid := GUID_DEVINTERFACE_USB_DEVI
dbi.dbcc_name := 0;
r := RegisterDeviceNotification
@dbi,
DEVICE_NOTIFY_WINDOW_HANDL
);
if Assigned( r ) then Result := True;
end;
end.
//////////////////////////
Good Luck!
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