Se me ocurren un par de formas de hacerlo.
Una es consultando la entrada del registro:
Código:
HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM
Es decir:
Código Delphi
[-]
uses Registry;
procedure GetPortList(List: TStringList);
var
i: integer;
begin
List.Clear;
with TRegistry.Create do
try
RootKey:= HKEY_LOCAL_MACHINE;
Access:= KEY_READ;
if OpenKey('HARDWARE\DEVICEMAP\SERIALCOMM',FALSE) then
begin
GetValueNames(List);
for i:= List.Count - 1 downto 0 do
List[i]:= ReadString(List[i]);
CloseKey;
end;
finally
Free;
end;
end;
var
List: TStringList;
begin
List:= TStringList.Create;
try
GetPortList(List);
Combobox1.Items.Assign(List);
finally
List.Free;
end;
end;
Ahora sería interesante saber si el puerto esta ocupado:
Código Delphi
[-]
function Ocupado(Puerto: String): Boolean;
var
Handle: THandle;
begin
Handle:= CreateFile(PChar('\\.\' + Puerto),GENERIC_READ or GENERIC_WRITE,0,
nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if Handle <> INVALID_HANDLE_VALUE then
begin
CloseHandle(Handle);
Result:= FALSE;
end else
Result:= TRUE;
end;
var
List: TStringList;
i: integer;
begin
List:= TStringList.Create;
try
GetPortList(List);
Combobox1.Items.Clear;
for i:= 0 to List.Count - 1 do
if not Ocupado(List[i]) then
Combobox1.Items.Add(List[i]);
finally
List.Free;
end;
end;
Pero ya que tenemos una función que nos dice si un puerto esta disponible, por que no la usamos también para listar los puertos. Solo tenemos que comprobar un numero razonable de puertos, aquí uso 10 pero si lo crees necesario usa 100.
Código Delphi
[-]
var
i: integer;
begin
Combobox1.Clear;
for i:= 0 to 10 do
if not Ocupado('COM' + IntToStr(i)) then
Combobox1.Items.Add('COM' + IntToStr(i));
end;