Windows supports 256 COM ports. While few PCs will have a large number of ports, with the proliferation of USB/serial adapters and ethernet/serial adapters, there may be several ports and they usually do not use contiguous numbers. Testing all 256 possibilities can be quite time consuming. I think it's best to first enumerate the ports, eliminate those that are infrared, modems, etc. and then test the remainder. This is much faster and more reliable. Do a Google search using "VB enumerate COM ports" and you will find lots of example code. Many examples check the registry but this is not an infallible method as users can edit the registry.
Here's an example written in PureBasic which uses the Windows API function EnumPorts. The backslash is PB's equivalent to VB's dot for referencing structure members (VB Type).
Code:
;--------------------------------------------------------
;
; SerialPorts.pbi
;
;--------------------------------------------------------
Structure API_PORT_INFO_2
PortName.s
MonitorName.s
Description.s
PortType.l
Reserved.l
EndStructure
Global NewList Portinfos.API_PORT_INFO_2()
Global ports.s
Global NumPorts.l
Procedure.l GetAvailablePorts(ServerName.s="")
Protected res.l, pcbNeeded.l,pcReturned .l,i.l,ret.l
Protected *TempBuff,*pName,*strPortinfos.PORT_INFO_2
If ServerName=""
*pName=0
Else
*pName=@ServerName
EndIf
;Get the number of bytes needed To contain the Data returned by the API call
ret = EnumPorts_(*pName, 2, 0, 0, @pcbNeeded, @pcReturned)
If pcbNeeded
*TempBuff = AllocateMemory(pcbNeeded) ; Allocate the Buffer
ret = EnumPorts_(*pName, 2, *TempBuff, pcbNeeded, @pcbNeeded, @pcReturned)
If ret
For i = 0 To pcReturned - 1
;set structure over the memory area
*strPortinfos.PORT_INFO_2=*TempBuff+(i*SizeOf(PORT_INFO_2))
AddElement(Portinfos())
Portinfos()\PortName=PeekS(*strPortinfos\pPortName)
Portinfos()\MonitorName=PeekS(*strPortinfos\pMonitorName)
Portinfos()\Description=PeekS(*strPortinfos\pDescription)
Portinfos()\PortType=*strPortinfos\fPortType
If Not FindString(LCase(Portinfos()\Description),"infrared",1)
If Not FindString(LCase(Portinfos()\Description),"modem",1)
If Not FindString(ports,Portinfos()\PortName,1)
If Left(Portinfos()\PortName,3)="COM" And FindString(Portinfos()\Description," Port",1)
;test each here by trying to open it
ports+Portinfos()\PortName
numPorts+1
EndIf
EndIf
EndIf
EndIf
Next
EndIf
;Free the Heap Space allocated for the Buffer
If *TempBuff
FreeMemory(*TempBuff)
EndIf
EndIf
ProcedureReturn pcReturned
EndProcedure
Here's a link to a VB example. http://vbnet.mvps.org/index.html?cod.../enumports.htm
EnumPorts returns all of the printer ports on the PC. The COM ports are a subset of the printer ports.
Bookmarks