除了从1循环到32并尝试打开它们之外,是否有可靠的方法来获得系统上的COM端口?如何枚举计算机上的可用COM端口?
2
A
回答
2
这是1〜255最快的,你可以做到这一点是使用QueryDosDevice
这样
Option Explicit
'--- for CreateFile
Private Const GENERIC_READ As Long = &H80000000
Private Const GENERIC_WRITE As Long = &H40000000
Private Const OPEN_EXISTING As Long = 3
Private Const INVALID_HANDLE_VALUE As Long = -1
'--- error codes
Private Const ERROR_ACCESS_DENIED As Long = 5&
Private Const ERROR_GEN_FAILURE As Long = 31&
Private Const ERROR_SHARING_VIOLATION As Long = 32&
Private Const ERROR_SEM_TIMEOUT As Long = 121&
Private Declare Function QueryDosDevice Lib "kernel32" Alias "QueryDosDeviceA" (ByVal lpDeviceName As Long, ByVal lpTargetPath As String, ByVal ucchMax As Long) As Long
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Function PrintError(sFunc As String)
Debug.Print sFunc; ": "; Error
End Function
Public Function IsNT() As Boolean
IsNT = True
End Function
Public Function EnumSerialPorts() As Variant
Const FUNC_NAME As String = "EnumSerialPorts"
Dim sBuffer As String
Dim lIdx As Long
Dim hFile As Long
Dim vRet As Variant
Dim lCount As Long
On Error GoTo EH
ReDim vRet(0 To 255) As Variant
If IsNT Then
sBuffer = String$(100000, 1)
Call QueryDosDevice(0, sBuffer, Len(sBuffer))
sBuffer = Chr$(0) & sBuffer
For lIdx = 1 To 255
If InStr(1, sBuffer, Chr$(0) & "COM" & lIdx & Chr$(0), vbTextCompare) > 0 Then
vRet(lCount) = "COM" & lIdx
lCount = lCount + 1
End If
Next
Else
For lIdx = 1 To 255
hFile = CreateFile("COM" & lIdx, GENERIC_READ Or GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0)
If hFile = INVALID_HANDLE_VALUE Then
Select Case Err.LastDllError
Case ERROR_ACCESS_DENIED, ERROR_GEN_FAILURE, ERROR_SHARING_VIOLATION, ERROR_SEM_TIMEOUT
hFile = 0
End Select
Else
Call CloseHandle(hFile)
hFile = 0
End If
If hFile = 0 Then
vRet(lCount) = "COM" & lIdx
lCount = lCount + 1
End If
Next
End If
If lCount = 0 Then
EnumSerialPorts = Split(vbNullString)
Else
ReDim Preserve vRet(0 To lCount - 1) As Variant
EnumSerialPorts = vRet
End If
Exit Function
EH:
PrintError FUNC_NAME
Resume Next
End Function
的片段回落到CreateFile
在Windows 9x。为简洁起见,函数被stubbed。
3
我相信在现代Windows环境下,你可以在注册表中找到它们,下面的键HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM
。我不确定指定注册表项的正确方法。不过,我只有在Windows XP上测试过它。
3
看看这篇文章从兰迪·伯奇的网站:CreateFile: Determine Available COM Ports
还有使用MSComm控件的方法:ConfigurePort: Determine Available COM Ports with the MSCOMM Control
代码有点太长了,我在这里发布,但链接有一切你需要。
相关问题
- 1. 使用RegQueryInfoKey()枚举COM端口
- 2. 枚举计算机内存
- 3. pyserial枚举端口
- 4. 计算枚举值
- 5. 枚举做计算
- 6. 如何枚举可用的代理服务器IP及端口
- 7. 枚举带驱动程序的COM端口
- 8. 如何枚举使用VBA在计算机上设置的DSN列表?
- 9. 如何枚举计算机所在子网的所有ip
- 10. 如何正确登录我的Applet以访问计算机的COM端口?
- 11. RegEx端口枚举验证
- 12. 将Silverlight连接到本地计算机COM端口
- 13. 容器如何枚举网络上可用的主机?
- 14. 枚举并做计算
- 15. 如何连接手机与COM端口
- 16. 用Jquery计算和枚举LI的
- 17. 在COM IDL中如何从COM依赖关系引用枚举?
- 18. 如何枚举端点url?
- 19. C#Com枚举和VB6
- 20. Xml序列化c#枚举只适用于某些计算机
- 21. 可扩展枚举计划
- 22. 如何枚举窗口LPT端口及其I/O范围?
- 23. 如何在我的计算机上阻止端口23上的数据包?
- 24. 计算机上同一端口上的Udp套接字通信
- 25. RXTX如何从COM端口
- 26. 如何解锁COM端口
- 27. 枚举的接口
- 28. 新的COM端口可用事件
- 29. 列出可用的COM端口
- 30. 发送方计算机如何知道接收方计算机上自定义进程的端口号?
例如...? – 2011-03-12 04:11:30
在.NET中这很容易,你有什么理由为什么使用VB6? – Arafangion 2011-03-12 04:19:40
@Arafangion遗留应用程序。 – AngryHacker 2011-03-12 04:41:26