79727821

Date: 2025-08-06 20:37:23
Score: 0.5
Natty:
Report link

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:

Getting Plugged in Devices using Delphi Programming Language


Is this kind of what you wanted?

Reasons:
  • Probably link only (1):
  • Long answer (-1):
  • Has code block (-0.5):
  • Ends in question mark (2):
  • High reputation (-1):
Posted by: Shaun Roselt