我目前正在学习如何创建批处理脚本,但到目前为止我只做查询。我可以在以下注册表路径上获取当前硬件、设备映射和串行 com 的列表
HKLM\hardware\devicemap\serialcomm
问题是每台计算机在同一设备上显示不同的
serialcomm
。所以我试图根据设备名称捕获serialcomm
。
我当前的代码如下:
reg query HKLM\hardware\devicemap\serialcomm
pause
下面是更新的代码,我尝试根据硬件名称获取
serialcomm
,但不起作用:(
set "Comm="
reg query HKLM\hardware\devicemap\serialcomm
if %%hardware%% = ProlificSerial0 set Comm=%%serialcomm%%
pause
上面的代码是根据我在多个网站上找到的所有信息创建的,但正如我所说,我仍在学习查询,对我来说添加更多代码有点复杂。
如果有人能告诉我更新后的代码有什么问题,我将不胜感激。
这里是一个批处理代码,其中包含一些解释性注释,是我几周前编写的,用于在安装设备驱动程序后使用 mySmartUSB MK2 作为虚拟串行通信端口安装,通过批处理文件对 Atmel AVR 控制器进行编程。用于对 AVR 控制器的熔丝位、闪存和 eeprom 进行编程的代码部分在此由简单的信息消息替换。
批处理文件确定COM端口号
对于这个问题,Windows注册表的识别是最有趣的部分。
DeviceInstance
、HardwareID
和 ProductName
必须适用于 Prolific USB 转串口转换器。
使用 Windows 注册表编辑器查看注册表项
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB
Prolific USB 转串口转换器的设备实例标识符和硬件标识符(供应商和产品标识符)。
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "ComPort="
set "DeviceInstance=mySmartUSB2-0001"
set "HardwareID=VID_10C4&PID_EA60"
set "ProductName=mySmartUSB MK2"
cls
echo(
call :ProcessArguments %*
call :CheckPort
echo Serial port of %ProductName% is: COM%ComPort%
echo(
endlocal
pause
exit /B
rem The subroutine ProcessArguments processes the optional parameters of
rem the batch file. For this demo everything except COMx with x being a
rem number in range 1 to 255 is interpreted as unknown parameter.
:ProcessArguments
set "EmptyLine=0"
:NextArgument
if "%~1" == "" (
if "%EmptyLine%" == "1" echo(
goto :EOF
)
set "SerialPort=%~1"
if /I "%SerialPort:~0,3%" == "com" (
set "ComPort=%SerialPort:~3%"
) else (
echo ERROR: Unknown parameter: %1
set "EmptyLine=1"
)
shift
goto NextArgument
rem The subroutine CheckPort checks the port number specified as parameter
rem on calling the batch file.
rem In case of no COM port number was specified as parameter, it attempts
rem to determine the COM port number for the device as defined at top of
rem the batch file directly from Windows registry. The registry query is
rem written to work for Windows XP and any later Windows.
rem Last in case of a valid COM port was whether passed to the batch file
rem via COMx parameter nor could the port number be determined from Windows
rem registry automatically, the user is prompted in a loop to enter a valid
rem port number.
:CheckPort
set "EmptyLine=0"
if not "%ComPort%" == "" goto VerifyPort
for /F "skip=2 tokens=1,3" %%A in ('%SystemRoot%\System32\reg.exe QUERY "HKLM\SYSTEM\CurrentControlSet\Enum\USB\%HardwareID%\%DeviceInstance%\Device Parameters" /v PortName 2^>nul') do (
if /I "%%A" == "PortName" set "SerialPort=%%B" && goto GetPortNumber
)
goto EnterPort
:GetPortNumber
if /I "%SerialPort:~0,3%" == "com" (
set "ComPort=%SerialPort:~3%"
goto VerifyPort
)
:EnterPort
set "EmptyLine=1"
set "ComPort=4"
set /P "ComPort=Enter number of COM port (default: %ComPort%): "
:VerifyPort
for /F "delims=0123456789" %%I in ("%ComPort%") do set "ComPort="
if "%ComPort%" == "" goto EnterPort
if %ComPort% EQU 0 goto EnterPort
if %ComPort% GTR 255 goto EnterPort
if "%EmptyLine%" == "1" echo(
goto :EOF
我认为,处理
HKLM\HARDWARE\DEVICEMAP\SERIALCOMM
是不可取的,因为它列出了所有串行设备,例如还包括调制解调器,而不仅仅是串行端口。此外,通过设备已知的硬件标识符,可以更快地直接找到 COM 端口号,如上所示。
如果具有相同供应商和产品标识符的多个设备同时连接到不同的 USB 端口,则
DeviceInstance
标识符通常以递增数字结尾。
因此,为了支持连接在同一台计算机上的多个 Prolific USB 转串口转换器,最好首先查询硬件标识符以获取所有设备实例标识符。
这是 ATEN USB 转串行桥适配器的一个非常简单的示例:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "HardwareID=VID_0557&PID_2008"
set "RegistryPath=HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB"
set "ProductName=ATEN USB to Serial Bridge"
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
exit /B
: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
注意: 两个批处理代码示例均不会检查每个找到的设备当前是否确实连接到计算机。这将需要额外的代码,即使与当前在
HKLM\HARDWARE\DEVICEMAP\SERIALCOMM
下注册的值进行交叉检查也是不够的,因为当拔出(虚拟)串行 COM 端口设备时,该注册表项不会自动更新。仅当插入串行 COM 端口设备时,它才会始终更新。
为了了解所使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并仔细阅读每个命令显示的所有帮助页面。
call /?
cls /?
echo /?
endlocal /?
exit /?
for /?
goto /?
if /?
pause /?
reg /?
reg query /?
rem /?
set /?
setlocal /?
shift /?
我的机器上没有串行通信,但您可以将此作为参考:
@echo off
for /f "tokens=3* delims= " %%a in (
'reg query HKLM\hardware\devicemap\pointerclass'
) do (
set "pointer=%%a"
)
echo %pointer%
if "%pointer%" equ "REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\mouclass" echo need to set something
您应该将要查找的特定值作为参数传递给批处理文件。例如,如果您的批处理文件名为 RegSearch,则命令行语法应类似于:
RegSearch ProlificSerial0
因此,您应该在批处理文件内进行一些语法检查,以确保在运行批处理文件时不会忘记指定参数。 此外,您可以将 /v 参数添加到 Reg Query 命令中,以便查找特定值(而不是查找所有键)。然后您可以使用 findstr 过滤查询结果以确定是否成功。
以下代码应该完成所有这些工作:
@echo off
setlocal enabledelayedexpansion
if /i "%1"=="" goto syntax
set myValue=%1
for /f "tokens=3 delims= " %%a in ('reg query hklm\hardware\devicemap\serialcomm /v *%myValue%* ^| findstr /i %myValue%') do (
set comm=%%a
echo !comm!
)
goto :eof
:syntax
echo.
echo ERROR : invalid syntax. You must pass the value to look for as the first argument, for example:
echo RegSearch Prolificserial0