Q:

How to retrieve serialcomm from a query?

I'm currently learning how to create batch scripts, but so far I am doing just queries. I am able to get a list of the current hardware, device map and serial com on the following registry path
HKLM\hardware\devicemap\serialcomm

The problem is that every computer is displaying a different serialcomm on the same device. So I am trying to capture the serialcomm based on the device name.
My current code below:
reg query HKLM\hardware\devicemap\serialcomm
pause

Below is an updated code I have tried to get the serialcomm based on the hardware name, but is not working :(
set "Comm="
reg query HKLM\hardware\devicemap\serialcomm
if %%hardware%% = ProlificSerial0 set Comm=%%serialcomm%%
pause

The above code was created based on all the information I have found on multiple websites, but as I said, I am still learning queries and it is a little bit complicated for me adding more code.
I will appreciate if anybody can tell me what is wrong with the updated code.

A:

Here is a batch code with some explaining comments which I wrote a few weeks ago to program Atmel AVR controllers via a batch file using mySmartUSB MK2 being mounted as virtual serial communication port after having once the device driver installed. The code part for programming the fuse bits, flash and eeprom of the AVR controllers is replaced here by a simple information message.
The batch file determines the COM port number

from one of several optional command line parameters (special option), or
queries it automatically directly from Windows registry (default method), or
asks the user of the batch file for the port number (fail safe method).

For the question the identification from Windows registry is the most interesting part.
DeviceInstance, HardwareID and ProductName must be adapted for the Prolific USB-to-Serial converter.
Look with Windows registry editor on registry key
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB

for the device instance identifier and hardware identifier (vendor and product identifier) for the Prolific USB-to-Serial converter.
@echo off
setlocal EnableExtensions
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
goto :EOF

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

I think, processing HKLM\HARDWARE\DEVICEMAP\SERIALCOMM is not advisable as it lists all serial devices including for example also modems and not only serial ports. Also with hardware identifier known for the device, the COM port number can be found out more quickly directly as demonstrated above.
The DeviceInstance identifier often ends with an incrementing number in case of several devices with same vendor and product identifier are connected at the same time on different USB ports.
So for supporting multiple Prolific USB-to-Serial converters connected on same computer it would be better to query first just the hardware identifier to get all device instance identifiers.
Here is a very simple example for ATEN USB to Serial Bridge adapter:
@echo off
setlocal EnableExtensions
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
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

Note: Both batch code examples do not check if each found device is really currently connected to the computer. That would require additional code whereby even cross-checking with values registered currently under HKLM\HARDWARE\DEVICEMAP\SERIALCOMM is not enough as this registry key is not automatically updated when a (virtual) serial COM port device is unplugged. It is only always updated when a serial COM port device is plugged in.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

call /?
cls /?
echo /?
endlocal /?
for /?
goto /?
if /?
pause /?
reg /?
reg query /?
rem /?
set /?
setlocal /?
shift /?

