如何仅获取特定USB设备当前使用的串行COM端口名称?

时间:2016-08-19 15:50:40

标签: batch-file

此网站的用户帮助我创建了以下代码,请参阅How to retrieve serialcomm from a query?

问题是显示的是设备连接的所有COM端口,我只需要知道它当前连接的端口。

我可能只需要改变一些东西,但我不确定它是什么。

@echo off
setlocal EnableExtensions
set "HardwareID=VID_067B&PID_2303"
set "RegistryPath=HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB"
set "ProductName=RS232 cable"
set "DeviceFound=0"

cls
echo.
for /F "delims=" %%I in ('%SystemRoot%\System32\reg.exe QUERY "%RegistryPath%\%HardwareID%" 2^>nul') do call :GetPort "%%I"

if "%DeviceFound%" == "0" echo WARNING: Could not find any %ProductName%.

echo.
endlocal
pause
goto :EOF

:GetPort
set "RegistryKey=%~1"
if /I not "%RegistryKey:~0,71%" == "%RegistryPath%\%HardwareID%\" goto :EOF

for /F "skip=2 tokens=1,3" %%A in ('%SystemRoot%\System32\reg.exe QUERY "%~1\Device Parameters" /v PortName 2^>nul') do (
    if /I "%%A" == "PortName" set "SerialPort=%%B" && goto OutputPort
)
goto :EOF

:OutputPort
set "DeviceFound=1"
set "DeviceNumber=%RegistryKey:~-1%"
echo %DeviceNumber%. %ProductName% is %SerialPort%.
goto :EOF

pause

1 个答案:

答案 0 :(得分:1)

这是我的第一个想法,它不是100%安全的连接状态检查,因为我已在How to retrieve serialcomm from a query?的答案中写道,因为注册表项下的字符串值

HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM
当从机器上拔下串行设备时,Windows不会立即更新

@echo off
setlocal EnableExtensions
set "HardwareID=VID_067B&PID_2303"
set "RegistryPath=HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB"
set "ProductName=RS232 cable"
set "DeviceFound=0"

cls
echo.
for /F "delims=" %%I in ('%SystemRoot%\System32\reg.exe QUERY "%RegistryPath%\%HardwareID%" 2^>nul') do call :GetPort "%%I"

if "%DeviceFound%" == "0" echo WARNING: Could not find any connected %ProductName%.

echo.
endlocal
pause
goto :EOF

:GetPort
set "RegistryKey=%~1"
if /I not "%RegistryKey:~0,71%" == "%RegistryPath%\%HardwareID%\" goto :EOF

for /F "skip=2 tokens=1,3" %%A in ('%SystemRoot%\System32\reg.exe QUERY "%~1\Device Parameters" /v PortName 2^>nul') do (
    if /I "%%A" == "PortName" set "SerialPort=%%B" && goto OutputPort
)
goto :EOF

:OutputPort
%SystemRoot%\System32\reg.exe query HKLM\HARDWARE\DEVICEMAP\SERIALCOMM | %SystemRoot%\System32\findstr.exe /E /I /L /C:%SerialPort% >nul
if errorlevel 1 goto :EOF
set "DeviceFound=1"
set "DeviceNumber=%RegistryKey:~-1%"
echo %DeviceNumber%. %ProductName% is %SerialPort%.
goto :EOF

我通过插入单词connected来修改警告,这是一个美容改进,但由于其他修改,这是一个重要的。

另一个修改是在子例程OutputPort中,其中插入了2个命令行,用于在设备映射中使用当前COM端口名称列表交叉检查找到的特定USB设备的COM端口名称。

reg.exe的输出被findstr.exe搜索,不区分大小写,因为之前检索到的串口字符串必须在输出行的末尾找到。

errorlevel分配给findstr.exe的退出代码为1,如果在reg.exe输出的任何行的末尾无法找到当前的COMx。这意味着USB端口A上的特定USB设备当前未连接,因此子例程将以goto :EOF退出。

但是如果在reg.exe的输出中确实存在以COMx结尾的行,则USB端口B(或C或D)上的特定USB设备(很可能)已连接,并且可以使用此串行通信端口通过申请。

在命令提示符窗口findstr /?中运行,以获取有关已使用选项的详细信息。

关于我的计算机上的串口管理的一个小故事,对读者来说可能很有意思:

我将我拥有的单个 ATEN USB连接到串行桥适配器一次连接到我的计算机的每个USB端口,然后在属性中的 Windows设备管理器中设置> > > >选项卡端口设置上的设备

因此,在我的Windows注册表中,此USB设备已使用COM1注册了4次,因此上面的批处理文件输出也是COM1的4倍,与我当前连接此适配器的USB端口无关。

没关系,因为我推翻了Windows标准的COM名称分配机制,为每个USB端口中的每个串行设备提供下一个未连接到此计算机的设备所使用的免费COM端口号。

对我来说最大的好处是 ATEN USB to Serial Bridge 适配器与COM1无关,我在哪个USB端口上插入适配器。但是,如果我有第二个 ATEN USB到串行桥适配器并将其另外插入另一个USB端口,我会遇到问题,需要在Windows设备管理器中再次更改COM端口同时使用两者。

有关串口号管理的其他信息:

我见过计算机,其中分配给新串行设备的COM端口已经非常高,如45.可以清理串行设备列表,从而从"使用的"中获取COM端口号。列表中的新串行设备。

必要的步骤是:

  1. Windows控制面板打开高级系统设置,然后点击环境变量按钮。
  2. 在包含系统变量的下方窗格中,点击按钮新建,然后添加名称为DEVMGR_SHOW_NONPRESENT_DEVICES且值为1的变量。
    在Windows Vista和更高版本的Windows版本中,将此环境变量定义为系统而非用户变量非常重要。
  3. 点击按钮确定
  4. ,关闭所有控制面板对话框窗口
  5. 在定义环境变量后立即打开 Windows控制面板 - 系统 - 设备管理器,然后在菜单项显示隐藏设备上单击菜单查看
  6. 现在不仅显示了真正存在但默认隐藏的设备,而且由于环境变量,所有不存在的设备都显示为灰色图标,如少数隐藏设备。

    因此,现在可以在端口(COM& LPT)下删除不存在的串行设备,从而释放相应的端口号。

    由于每个USB转串口适配器在通用串行总线控制器下也有设备条目,建议在删除串行设备之前双击串行设备以打开属性,在关闭属性窗口并删除之前,切换到标签详细信息,选择硬件ID 并记下供应商标识符(VID)和产品标识符(PID)串口设备。应删除具有相同VID和PID的USB设备。

    额外注意:在磁盘驱动器便携式设备存储卷通用串行总线控制器。一般情况下,删除所有灰色设备是安全的 非即插即用驱动程序网络适配器声音,视频和游戏控制器,因为这些类别总是包含隐藏设备。