I asked the same question in 2011 and got the following, abbreviated solution :
unit Main01;
{$mode objfpc}{$H+}
........
interface
uses
Classes, Controls, Dialogs, ExtCtrls, FileUtil, Forms, Graphics, Registry,
StdCtrls, Synaser, SysUtils;
type
{ TForm1 }
private
{ private declarations }
public
{ public declarations }
end;
var
Form1 : TForm1;
ser1 : TBlockSerial;
Line : String;
implementation
uses Unit2;
{$R *.lfm}
{ TForm1 }
procedure TForm1.BtnRunClick(Sender: TObject);
Var
reg: TRegistry;
L : TStringList;
n: integer;
Str1, Str2: String;
begin
L := TStringList.Create;
reg := TRegistry.Create;
try
{$IFNDEF VER100}
reg.Access := KEY_READ;
{$ENDIF}
reg.RootKey := HKEY_LOCAL_MACHINE;
reg.OpenKeyReadOnly('HARDWARE\DEVICEMAP\SERIALCOMM');//, false);
reg.GetValueNames(L);
for n := 0 to l.Count - 1 do
begin
Str1 := L[n];
Str2 := reg.ReadString(L[n]);
Memo1.Lines.Add(Str1 + ': ' + Str2);
end;
end;
finally
reg.Free;
L.Free;
end;
end;
END.
I have used it regularly since.