设备接口事件,获取设备名称
Device Interface Events, Get Device Name
基于this blog post,我写了一些检测USB设备的代码:
PDevBroadcastDeviceInterface = ^DEV_BROADCAST_DEVICEINTERFACE;
DEV_BROADCAST_DEVICEINTERFACE = record
dbcc_size : DWORD;
dbcc_devicetype : DWORD;
dbcc_reserved : DWORD;
dbcc_classguid : TGUID;
dbcc_name : char;
end;
.
.
.
procedure TUsbClass.RegisterUsbHandler;
var rDbi : DEV_BROADCAST_DEVICEINTERFACE;
iSize : integer;
begin
iSize := SizeOf(DEV_BROADCAST_DEVICEINTERFACE);
ZeroMemory(@rDbi,iSize);
rDbi.dbcc_size := iSize;
rDbi.dbcc_devicetype := USB_INTERFACE;
rDbi.dbcc_reserved := 0;
rDbi.dbcc_classguid := GUID_DEVINTF_USB_DEVICE;
rDbi.dbcc_name := #0;
RegisterDeviceNotification(FHandle,@rDbi,DEVICE_NOTIFY_WINDOW_HANDLE);
end;
procedure TUsbClass.WMDeviceChange(var AMessage : TMessage);
var iDevType : integer;
sDevString,sDevType,
sDriverName,sFriendlyName : string;
pData : PDevBroadcastDeviceInterface;
pVol : PDEV_BROADCAST_VOLUME;
begin
if (AMessage.wParam = USB_INSERTION) or
(AMessage.wParam = USB_REMOVAL) then begin
pData := PDevBroadcastDeviceInterface(AMessage.LParam);
iDevType := pData^.dbcc_devicetype;
if iDevType = USB_VOLUME then
if Assigned(FOnDevVolumeEvent) then begin
...
end
else
else
// Is it a USB Interface Device ?
if iDevType = USB_INTERFACE then begin
sDevString := PChar(@pData^.dbcc_name);
...
end;
end;
end;
一切正常,插入 USB 设备时我确实收到事件,但问题是 sDevString
始终是空字符串。我也试过检测 WPD 设备(通过将 rDbi.dbcc_classguid
设置为正确的 GUID 值)并且它工作正常,除了我总是得到一个空字符串 sDevString
。如何获得正确的设备名称?
您 link 文章中的代码在添加到干净的项目后可以正常工作。当一个 USB 设备,例如插入闪存驱动器,分配给 sDevString
的值不为空,并且包含正确的设备字符串。
我只能想象有一些您没有显示的额外代码令人困惑。
我建议您逐字使用文章中的代码。复制并粘贴整个单元。那篇文章的作者在使代码易于使用方面做得很好。您直接使用该单元即可,无需进行任何更改。
如果您希望修改代码,可以这样做。但是一旦您确信所提供的代码有效,您就会知道是您的更改导致了任何失败。
基于this blog post,我写了一些检测USB设备的代码:
PDevBroadcastDeviceInterface = ^DEV_BROADCAST_DEVICEINTERFACE;
DEV_BROADCAST_DEVICEINTERFACE = record
dbcc_size : DWORD;
dbcc_devicetype : DWORD;
dbcc_reserved : DWORD;
dbcc_classguid : TGUID;
dbcc_name : char;
end;
.
.
.
procedure TUsbClass.RegisterUsbHandler;
var rDbi : DEV_BROADCAST_DEVICEINTERFACE;
iSize : integer;
begin
iSize := SizeOf(DEV_BROADCAST_DEVICEINTERFACE);
ZeroMemory(@rDbi,iSize);
rDbi.dbcc_size := iSize;
rDbi.dbcc_devicetype := USB_INTERFACE;
rDbi.dbcc_reserved := 0;
rDbi.dbcc_classguid := GUID_DEVINTF_USB_DEVICE;
rDbi.dbcc_name := #0;
RegisterDeviceNotification(FHandle,@rDbi,DEVICE_NOTIFY_WINDOW_HANDLE);
end;
procedure TUsbClass.WMDeviceChange(var AMessage : TMessage);
var iDevType : integer;
sDevString,sDevType,
sDriverName,sFriendlyName : string;
pData : PDevBroadcastDeviceInterface;
pVol : PDEV_BROADCAST_VOLUME;
begin
if (AMessage.wParam = USB_INSERTION) or
(AMessage.wParam = USB_REMOVAL) then begin
pData := PDevBroadcastDeviceInterface(AMessage.LParam);
iDevType := pData^.dbcc_devicetype;
if iDevType = USB_VOLUME then
if Assigned(FOnDevVolumeEvent) then begin
...
end
else
else
// Is it a USB Interface Device ?
if iDevType = USB_INTERFACE then begin
sDevString := PChar(@pData^.dbcc_name);
...
end;
end;
end;
一切正常,插入 USB 设备时我确实收到事件,但问题是 sDevString
始终是空字符串。我也试过检测 WPD 设备(通过将 rDbi.dbcc_classguid
设置为正确的 GUID 值)并且它工作正常,除了我总是得到一个空字符串 sDevString
。如何获得正确的设备名称?
您 link 文章中的代码在添加到干净的项目后可以正常工作。当一个 USB 设备,例如插入闪存驱动器,分配给 sDevString
的值不为空,并且包含正确的设备字符串。
我只能想象有一些您没有显示的额外代码令人困惑。
我建议您逐字使用文章中的代码。复制并粘贴整个单元。那篇文章的作者在使代码易于使用方面做得很好。您直接使用该单元即可,无需进行任何更改。
如果您希望修改代码,可以这样做。但是一旦您确信所提供的代码有效,您就会知道是您的更改导致了任何失败。