I made a unit for you to do this:
unit DeviceLister;
interface
uses
System.Classes
,System.SysUtils
{$IFDEF MSWINDOWS}
,Winapi.Windows
{$ENDIF};
function GetPluggedInDevices: TStringList;
implementation
{$IFDEF MSWINDOWS}
const
DIGCF_PRESENT = $00000002;
DIGCF_ALLCLASSES = $00000004;
SPDRP_DEVICEDESC = $00000000;
type
HDEVINFO = Pointer;
ULONG_PTR = NativeUInt;
TSPDevInfoData = packed record
cbSize: DWORD;
ClassGuid: TGUID;
DevInst: DWORD;
Reserved: ULONG_PTR;
end;
function SetupDiGetClassDevsW(ClassGuid: PGUID; Enumerator: PWideChar; hwndParent: HWND;
Flags: DWORD): HDEVINFO; stdcall; external 'setupapi.dll' name 'SetupDiGetClassDevsW';
function SetupDiEnumDeviceInfo(DeviceInfoSet: HDEVINFO; MemberIndex: DWORD;
var DeviceInfoData: TSPDevInfoData): BOOL; stdcall; external 'setupapi.dll';
function SetupDiGetDeviceRegistryPropertyW(DeviceInfoSet: HDEVINFO;
const DeviceInfoData: TSPDevInfoData; Property_: DWORD; var PropertyRegDataType: DWORD;
PropertyBuffer: PBYTE; PropertyBufferSize: DWORD; RequiredSize: PDWORD): BOOL; stdcall; external 'setupapi.dll' name 'SetupDiGetDeviceRegistryPropertyW';
function SetupDiDestroyDeviceInfoList(DeviceInfoSet: HDEVINFO): BOOL; stdcall; external 'setupapi.dll';
{$ENDIF}
function GetPluggedInDevices: TStringList;
{$IFDEF MSWINDOWS}
var
DeviceInfoSet: HDEVINFO;
DeviceInfoData: TSPDevInfoData;
i: Integer;
DeviceName: array[0..1023] of Byte;
RegType: DWORD;
{$ENDIF}
begin
Result := TStringList.Create;
{$IFDEF MSWINDOWS}
DeviceInfoSet := SetupDiGetClassDevsW(nil, nil, 0, DIGCF_ALLCLASSES or DIGCF_PRESENT);
if NativeUInt(DeviceInfoSet) = NativeUInt(INVALID_HANDLE_VALUE) then
begin
Result.Add('Failed to get device list.');
Exit;
end;
i := 0;
DeviceInfoData.cbSize := SizeOf(TSPDevInfoData);
while SetupDiEnumDeviceInfo(DeviceInfoSet, i, DeviceInfoData) do
begin
if SetupDiGetDeviceRegistryPropertyW(DeviceInfoSet, DeviceInfoData, SPDRP_DEVICEDESC,
RegType, @DeviceName, SizeOf(DeviceName), nil) then
begin
Result.Add(Format('%d: %s', [i + 1, PWideChar(@DeviceName)]));
end;
Inc(i);
end;
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
{$ELSE}
Result.Add('Device listing is only supported on Windows.');
{$ENDIF}
end;
end.
And then in your app, you can simply add DeviceLister
to your uses list, and then call the GetPluggedInDevices
function. Here's an example where I'm calling and using it on a button to display the devices onto a memo:
procedure TForm1.Button1Click(Sender: TObject);
begin
var Devices := GetPluggedInDevices;
Memo1.Lines.Assign(Devices);
Devices.Free;
end;
And the result:
Is this kind of what you wanted?