RAD Studio Quickly Enumerate Through USB Devices With Code On Windows

FireWind

Свой
Регистрация
2 Дек 2005
Сообщения
1,957
Реакции
1,199
Credits
4,009
Quickly Enumerate Through USB Devices With Code On Windows
March 4, 2021 By Anbarasan

Sometimes Developers Want to list or Identify USB devices connected to the machine and perform some actions to the USB devices programmatically. How to enumerate among the USB devices quickly ? Don’t know how to do. Don’t worry. Для просмотра ссылки Войди или Зарегистрируйся System Information Management Suite’s component helps to enumerate the connected USB devices we will learn how to use use the TMiTec_USB component in this blog post.

Platforms: Windows.

Installation Steps:

You can easily install this Component Suite from GetIt Package Manager. The steps are as follows.
  1. Navigate In RAD Studio IDE->Tools->GetIt Package Manager->select Components in Categories->Components->Trail -MiTec system Information Component Suite 14.3 and click Install Button.
  2. Read the license and Click Agree All. An Information dialog saying ‘Requires a restart of RAD studio at the end of the process. Do you want to proceed? click yes and continue.
  3. It will download the plugin and installs it. Once installed Click Restart now.
How to run the Demo app:
  • Navigate to the System Information Management Suite trails setup, Demos folder which is installed during Get It installation e.g) C:UsersDocumentsEmbarcaderoStudio21.0CatalogRepositoryMiTeC-14.3DemosDelphi4
  • Open the USBEnum project in RAD studio 10.4.1 compile and Run the application.
  • This Demo App shows how to list down the connected USB devices, enumerate among them and access its properties.
Components used in MSIC USBEnum Demo App:
1614935958611.png
  • TMiTeC_USB: Enumerates all connected USB devices and their properties.
  • TMiTec_DeviceMonitor : Catches USB, Bluetooth devices or TV/monitor connection/disconnection, volumes mount/unmount, CD/DVD insert/eject and other events from other devices
  • TTreeView to list the USB devices nodes and TListView to show the connected USB Device Node properties.
  • TButton’s to save, refresh and eject selected USB device.
Implementation Details:

  • An instance is created USB of TMiTeC_USB. Call USB.RefreshData, Add list of USB nodes to the tree node by loop through USB.USBNodeCount. Ensure the USB Devices is connected before adding its property value to the list view.
Код:
procedure TForm1.RefreshData;
var
  ii,i,j: Integer;
  s: string;
  pi: PInteger;
  r,n,c: TTreeNode;
  g: TGUID;
begin
  USB.RefreshData;
  Caption:=Format('USB Devices (%d connected)',[USB.ConnectedDevices]);
  Tree.Items.BeginUpdate;
  try
  Tree.Items.Clear;
  for i:=0 to USB.USBNodeCount-1 do
    with USB.USBNodes[i] do begin
      s:='';
      if ClassGUID.D1=0 then
        g:=GUID_DEVCLASS_USB
      else
        g:=ClassGUID;
      SetupDiGetClassImageIndex(spid,g,ii);
      case USBClass of
        usbHostController: s:=s+Format('%s %d',[ClassNames[Integer(USBClass)],USBDevice.Port]);
        usbHub: s:=s+Format('%s (%s)',[USBDevice.USBClassname,ClassNames[Integer(USBClass)]]);
        else begin
          if USBDevice.ConnectionStatus=1 then begin
            if USBClass=usbExternalHub then
              s:=s+Format('Port[%d]: %s (%s)',[USBDevice.Port,USBDevice.USBClassname,ClassNames[Integer(USBClass)]])
            else begin
              if USBDevice.Product<>'' then
                s:=s+Format('Port[%d]: %s',[USBDevice.Port,USBDevice.Product])
              else
                s:=s+Format('Port[%d]: %s',[USBDevice.Port,USBDevice.USBClassname]);
              if IsEqualGUID(g,GUID_DEVCLASS_USB) and (Length(USBDevice.Registry)>0) then begin
                g:=USBDevice.Registry[0].DeviceClassGUID;
                SetupDiGetClassImageIndex(spid,g,ii);
              end;
            end;
          end else
            s:=s+Format('Port[%d]: %s',[USBDevice.Port,ConnectionStates[USBDevice.ConnectionStatus]]);
        end;
      end;
      r:=FindNode(ParentIndex);
      new(pi);
      pi^:=i;
      n:=Tree.Items.AddChildObject(r,s,pi);
      n.ImageIndex:=ii;
      n.SelectedIndex:=n.ImageIndex;
      if Assigned(r) then
        r.Expand(False);
      r:=n;
      if (USBClass in [usbReserved..usbStorage,usbVendorSpec,usbError]) and (USBDevice.ConnectionStatus=1) then begin
        for j:=0 to High(USBDevice.Registry) do begin
          g:=USBDevice.Registry[j].DeviceClassGUID;
          SetupDiGetClassImageIndex(spid,g,ii);
          new(pi);
          pi^:=MakeWord(j,i+1);
          n:=Tree.Items.AddChildObject(r,USBDevice.Registry[j].DeviceClass,pi);
          n.ImageIndex:=ii;
          n.SelectedIndex:=n.ImageIndex;
          if (USBDevice.Registry[j].Drive<>'') and USBDevice.Registry[j].DriveConnected then begin
            new(pi);
            pi^:=MakeWord(j,i+1);
            c:=Tree.Items.AddChildObject(n,Format('Drive: %s:',[USBDevice.Registry[j].Drive]),pi);
            g:=GUID_DEVCLASS_VOLUME;
            SetupDiGetClassImageIndex(spid,g,ii);
            c.ImageIndex:=ii;
            c.SelectedIndex:=c.ImageIndex;
          end;
        end;
      end;
    end;
  finally
    Tree.Items.EndUpdate;
  end;
end;
  • Display the selected USB Device Node properties as shown below.
Код:
procedure TForm1.DisplayProps(AIndex: integer);
 
procedure AddItem(const AProperty,AValue: string);
begin
  with List.Items.Add do begin
    Caption:=AProperty;
    SubItems.Add(AValue);
  end;
end;
 
var
  s: string;
begin
  List.Items.BeginUpdate;
  try
    List.Items.Clear;
    if AIndex<256 then begin
      with USB.USBNodes[AIndex] do
        if (USBDevice.ConnectionStatus=1) then begin
          if USBDevice.USBClassname='' then
            AddItem('Class',ClassNames[Integer(USBClass)])
          else
            AddItem('Class',USBDevice.USBClassName);
          AddItem('Manufacturer',USBDevice.Manufacturer);
          if (USBClass in [usbReserved..usbStorage,usbVendorSpec,usbError]) then begin
            AddItem('ClassGUID',GUIDToString(ClassGUID));
            AddItem('Connection Name',ConnectionName);
            AddItem('Serial',USBDevice.Serial);
            AddItem('Power consumption',Format('%d mA',[USBDevice.MaxPower]));
            case USB.GetDevicePowerState(DeviceInstanceId,Keyname) of
              PowerDeviceUnspecified: s:='Unspecified';
              PowerDeviceD0: s:='D0';
              PowerDeviceD1: s:='D1';
              PowerDeviceD2: s:='D2';
              PowerDeviceD3: s:='D3';
            end;
            AddItem('Power state',s);
            AddItem('Specification version',Format('%d.%d',[USBDevice.MajorVersion,USBDevice.MinorVersion]));
            AddItem('Driver key',Keyname);
            AddItem('Last init',DateTimeToStr(TimeStamp));
          end;
        end;
    end else
      with USB.USBNodes[Hi(AIndex)-1] do begin
        AddItem('Class',USBDevice.Registry[Lo(AIndex)].DeviceClass);
        AddItem('Name',USBDevice.Registry[Lo(AIndex)].Name);
        AddItem('ClassGUID',GUIDToString(USBDevice.Registry[Lo(AIndex)].DeviceClassGUID));
        AddItem('Last init',DateTimeToStr(USBDevice.Registry[Lo(AIndex)].Timestamp));
      end;
  finally
    List.Items.EndUpdate;
  end;
end;
  • On clicking Remove Button, Check whether the selected USB Device Node is eject able using Method IsEjectable and Eject the Device.
  • Use DeviceMonitor events OnDevicConnect, OnDeviceDisconnect, OnVolumeConnect, OnVolumeDisconnect to identify the device arrival/removal and refresh the tree view accordingly.
Код:
procedure TForm1.DeviceMonitorDeviceConnect(Sender: TObject;
  DeviceDesc: TDeviceDesc);
begin
  if cbxAuto.Checked and SameText(DeviceDesc.GUID,GUIDToString(GUID_DEVINTERFACE_USB_DEVICE)) then
    Refreshdata;
end;
 
procedure TForm1.DeviceMonitorVolumeConnect(Sender: TObject; Drive: Char;
  Remote: Boolean);
begin
  if cbxAuto.Checked then
    Refreshdata;
end;
1614936029793.png
MiTeC USBEnum Demo

It’s that simple to enumerate USB Devices connected and list its properties for your application. Use this MiTeC component suite and get the job done quickly.