- 註冊時間
- 2006-3-13
- 最後登錄
- 2025-1-10
- 在線時間
- 673 小時
- 閱讀權限
- 200
- 積分
- 417
- 帖子
- 1107
- 精華
- 0
- UID
- 2
  
|
只有 COMn 的列表也不是很確定是對應到哪個設備,需要更友善的資訊
http://delphi.cjcsoft.net/viewthread.php?tid=45021
Enumerating available comm ports with friendly names.
Title: Enumerating available comm ports with friendly names.
Question: Serial (and virtual serial) PNP Devices (PCMCIA, USB, Bluetooth) get assigned "arbitrary" comm port numbers.
To help users to select the correct comm port it would be helpfull to list them with device friendly names.
The supplied function helps this goal.
Answer:- (*
- The function below returns a list of available COM-ports
- (not open by this or an other process), with friendly names. The list is formatted as follows:
- COM1: = Communications Port (COM1)
- COM5: = NI Serial Port (Com5)
- COM6: = NI Serial Port (Com6)
- COM7: = USB Serial Port (COM7)
- COM8: = Bluetooth Communications Port (COM8)
- COM9: = Bluetooth Communications Port (COM9)
- The function uses the setupapi (setup api) unit that is available from
- "http://homepages.borland.com/jedi/cms/modules/apilib/visit.php?cid=4&lid=3".
- I have verified the code and it worked for W2000, WXP, W98. It does not work for W95, and NT 4.0. I did not check WME but I guess it will work with WME too.
- *)
- function SetupEnumAvailableComPorts:TstringList;
- // Enumerates all serial communications ports that are available and ready to
- // be used.
- // For the setupapi unit see
- // http://homepages.borland.com/jedi/cms/modules/apilib/visit.php?cid=4&lid=3
- var
- RequiredSize: Cardinal;
- Guid: TGUID;
- DevInfoHandle: HDEVINFO;
- DeviceInfoData: TSPDevInfoData;
- MemberIndex: Cardinal;
- PropertyRegDataType: DWord;
- RegProperty: Cardinal;
- RegTyp: Cardinal;
- Key: Hkey;
- Info: TRegKeyInfo;
- S1,S2: string;
- hc: THandle;
- begin
- Result:=Nil;
- //If we cannot access the setupapi.dll then we return a nil pointer.
- if not LoadsetupAPI then exit;
- try
- // get 'Ports' class guid from name
- if SetupDiClassGuidsFromName('Ports',@Guid,RequiredSize,RequiredSize) then begin
- //get object handle of 'Ports' class to interate all devices
- DevInfoHandle:=SetupDiGetClassDevs(@Guid,Nil,0,DIGCF_PRESENT);
- if Cardinal(DevInfoHandle)Invalid_Handle_Value then begin
- try
- MemberIndex:=0;
- result:=TStringList.Create;
- //iterate device list
- repeat
- FillChar(DeviceInfoData,SizeOf(DeviceInfoData),0);
- DeviceInfoData.cbSize:=SizeOf(DeviceInfoData);
- //get device info that corresponds to the next memberindex
- if Not SetupDiEnumDeviceInfo(DevInfoHandle,MemberIndex,DeviceInfoData) then
- break;
- //query friendly device name LIKE 'BlueTooth Communication Port (COM8)' etc
- RegProperty:=SPDRP_FriendlyName;{SPDRP_Driver, SPDRP_SERVICE, SPDRP_ENUMERATOR_NAME,SPDRP_PHYSICAL_DEVICE_OBJECT_NAME,SPDRP_FRIENDLYNAME,}
- SetupDiGetDeviceRegistryProperty(DevInfoHandle,DeviceInfoData,
- RegProperty,
- @PropertyRegDataType,
- NIL,0,@RequiredSize);
- SetLength(S1,RequiredSize);
- if SetupDiGetDeviceRegistryProperty(DevInfoHandle,DeviceInfoData,
- RegProperty,
- @PropertyRegDataType,
- @S1[1],RequiredSize,@RequiredSize) then begin
- KEY:=SetupDiOpenDevRegKey(DevInfoHandle,DeviceInfoData,DICS_FLAG_GLOBAL,0,DIREG_DEV,KEY_READ);
- if keyINValid_Handle_Value then begin
- FillChar(Info, SizeOf(Info), 0);
- //query the real port name from the registry value 'PortName'
- if RegQueryInfoKey(Key, nil, nil, nil, @Info.NumSubKeys,@Info.MaxSubKeyLen, nil, @Info.NumValues, @Info.MaxValueLen,
- @Info.MaxDataLen, nil, @Info.FileTime) = ERROR_SUCCESS then begin
- RequiredSize:= Info.MaxValueLen + 1;
- SetLength(S2,RequiredSize);
- if RegQueryValueEx(KEY,'PortName',Nil,@Regtyp,@s2[1],@RequiredSize)=Error_Success then begin
- If (Pos('COM',S2)=1) then begin
- //Test if the device can be used
- hc:=CreateFile(pchar('\\.\'+S2+#0),
- GENERIC_READ or GENERIC_WRITE,
- 0,
- nil,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- 0);
- if hc INVALID_HANDLE_VALUE then begin
- Result.Add(Strpas(PChar(S2))+': = '+StrPas(PChar(S1)));
- CloseHandle(hc);
- end;
- end;
- end;
- end;
- RegCloseKey(key);
- end;
- end;
- Inc(MemberIndex);
- until False;
- //If we did not found any free com. port we return a NIL pointer.
- if Result.Count=0 then begin
- Result.Free;
- Result:=NIL;
- end
- finally
- SetupDiDestroyDeviceInfoList(DevInfoHandle);
- end;
- end;
- end;
- finally
- UnloadSetupApi;
- end;
- end;
複製代碼 |
|