Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serial (COM) ports name or identification

Tags:

delphi

I've a program that access multiple serial ports using cport.

To configure, till now I simply listed all available comports in a combobox to make a selection, but the increasing number of drivers with (virtual) serial interfaces makes configuring for end-users troublesome.

The current detection works with createfile(), but that has the problem that you only get exists/nonexists and maybe "busy" as information.

However to improve, I need per COM port a identification string, like the hardware device/driver (device manager) it is connected too. This would make it easier for the user to narrow the comports down (since we deliver a finite number of serial cards)

Probably it is available from WMI, but that's quite a jungle, does sb have more concrete information, or better, code?

(Delphi XE3, Win7+, no solution that requires additional installing or deployment please)

like image 447
Marco van de Voort Avatar asked Apr 19 '13 08:04

Marco van de Voort


People also ask

How do I identify my COM ports?

Open Device Manager (Start → Control Panel → Hardware and Sound → Device Manager) Look in the Device Manager list, open the category "Ports", and find the matching COM Port. Take the number in the bracket behind the port description.

Why are serial ports called COM ports?

An asynchronous port on the computer used to connect a serial device to the computer and capable of transmitting one bit at a time. Serial ports are usually identified on IBM compatible computers as COM (communications) ports. For example, a mouse might connect to COM1 and a modem to COM2.

What are the types of serial ports?

There are two types of serial ports that are commonly found on a computer: DB-25 and DE-9.


1 Answers

If you want enumerate the COM ports getting a friendly name you can use the SetupAPI and the GUID_DEVINTERFACE_COMPORT device interface class.

Try this sample

{$APPTYPE CONSOLE}

{$R *.res}

uses
  Windows,
  SysUtils,
  JvSetupApi;

const
  GUID_DEVINTERFACE_COMPORT:TGUID='{86E0D1E0-8089-11D0-9CE4-08003E301F73}';

procedure EnumerateCOMPorts;
var
   cbRequired : DWORD;
   hdev     : HDEVINFO;
   idev     : Integer;
   did      : TSPDeviceInterfaceData;
   pdidd    : PSPDeviceInterfaceDetailData;
   PropertyBuffer : array[0..255] of Char;
   DeviceInfoData: TSPDevInfoData;
   PropertyRegDataType: DWORD;
   RequiredSize: DWORD;
begin
  // enumerate the com ports
  hdev :=  SetupDiGetClassDevs(@GUID_DEVINTERFACE_COMPORT, nil, 0,  DIGCF_PRESENT OR DIGCF_DEVICEINTERFACE);
  if ( INVALID_HANDLE_VALUE <>  THandle(hdev) ) then
  begin
    try
      idev:=0;
      ZeroMemory(@did, SizeOf(did));
      did.cbSize := SizeOf(did);
      repeat
        if (SetupDiEnumDeviceInterfaces(hdev, nil, GUID_DEVINTERFACE_COMPORT, idev, did)) then
        begin
            cbRequired := 0;
            SetupDiGetDeviceInterfaceDetail(hdev, @did, nil, 0, cbRequired, nil);
           if (ERROR_INSUFFICIENT_BUFFER= GetLastError()) then
           begin
              pdidd:=AllocMem(cbRequired);
              try
                pdidd.cbSize := SizeOf(TSPDeviceInterfaceDetailData);
                DeviceInfoData.cbSize:= SizeOf(DeviceInfoData);
                RequiredSize:=0;
                if (SetupDiGetDeviceInterfaceDetail(hdev, @did, pdidd, cbRequired, RequiredSize, @DeviceInfoData)) then
                begin

                 PropertyRegDataType:=0;
                 RequiredSize:=0;
                 if SetupDiGetDeviceRegistryProperty(hdev, DeviceInfoData, SPDRP_FRIENDLYNAME, PropertyRegDataType,  PBYTE(@PropertyBuffer[0]), SizeOf(PropertyBuffer), RequiredSize) then
                  Writeln(Format('Friendly Name - %s',[PropertyBuffer]));

                 if SetupDiGetDeviceRegistryProperty(hdev, DeviceInfoData, SPDRP_DEVICEDESC, PropertyRegDataType,  PBYTE(@PropertyBuffer[0]), SizeOf(PropertyBuffer), RequiredSize) then
                  Writeln(Format('Description   - %s',[PropertyBuffer]));

                 if SetupDiGetDeviceRegistryProperty(hdev, DeviceInfoData, SPDRP_LOCATION_INFORMATION, PropertyRegDataType,  PBYTE(@PropertyBuffer[0]), SizeOf(PropertyBuffer), RequiredSize) then
                  Writeln(Format('Location      - %s',[PropertyBuffer]));
                end
                else
                RaiseLastOSError;
              finally
                FreeMem(pdidd);
              end;
           end;
        end
        else
        Break;
        inc(idev);
      until false;
    finally
      SetupDiDestroyDeviceInfoList(hdev);
    end;
  end;
end;

begin
  try
    if not LoadsetupAPI then exit;
     EnumerateCOMPorts;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  readln;
end.

This will return something like so

enter image description here

Note : The JvSetupApi unit is part of the JVCL library.

like image 157
RRUZ Avatar answered Sep 28 '22 02:09

RRUZ