Search code examples
windowsbatch-filewindows-7registrylogical-operators

batch file reg query with logical operators (NOT)


I am trying to write a reg query batch file that looks for key data that does NOT contain something. Currently, this code searches for a key Dependent Files (REG_MULTI_SZ) and will write the output to a file. I need it to ignore any data within Dependent Files containing "**.GPD*".

How do I incorporate logical operators into a simple REG QUERY?

@echo off
set file=c:\Temp\regcomplist.txt
for /f "Tokens=*" %%g in (%file%) do (
    echo %%g>> c:\Temp\regquery.txt
    REG QUERY "\\%%g\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Environments\Windows x64\Drivers\Version-3\Lexmark Universal v2 XL" /v "Dependent Files">> c:\Temp\regquery.txt
    echo.>> c:\Temp\regquery.txt
    echo.>> c:\Temp\regquery.txt
)

Solution

  • The batch code with using the command as suggested by rojo is:

    @echo off
    set "ListFile=C:\Temp\regcomplist.txt"
    set "ResultsFile=C:\Temp\regquery.txt"
    for /f "delims=" %%g in (%ListFile%) do (
        echo %%g>>%ResultsFile%
        %SystemRoot%\System32\reg.exe query "\\%%g\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Environments\Windows x64\Drivers\Version-3\Lexmark Universal v2 XL" /v "Dependent Files" | %SystemRoot%\System32\find.exe /i /v "**.GPD*">>%ResultsFile%
        echo.>>%ResultsFile%
        echo.>>%ResultsFile%
    )
    

    After adding information that registry value Dependent Files is of type REG_MULTI_SZ, I went to a computer having a printer installed (my one has not) and exported the registry key of this printer with regedit to a .reg file. Next I imported this registry file into registry of my computer and executed once reg query for this key to see how the multiline value is written to console by reg.

    Then I could develop the commented batch file below.

    @echo off
    setlocal EnableDelayedExpansion
    
    set "Printer=Lexmark Universal v2 XL"
    set "ListFile=C:\Temp\regcomplist.txt"
    set "ResultsFile=C:\Temp\regquery.txt"
    if exist "%ResultsFile%" del "%ResultsFile%"
    
    rem Run the procedure GetPrinterFiles on each computer of list file.
    for /f "delims=" %%g in (%ListFile%) do (
        echo %%g>>%ResultsFile%
        call :GetPrinterFiles "%%g"
        echo.>>%ResultsFile%
        echo.>>%ResultsFile%
    )
    endlocal
    rem Exit this batch file.
    goto :EOF
    
    rem Get multiline string with the file names from registry and parse that
    rem string with procedure GetFileNames if the printer is installed at all.
    
    :GetPrinterFiles
    for /F "skip=2 tokens=3*" %%A in ('%SystemRoot%\System32\reg.exe query "\\%~1\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Environments\Windows x64\Drivers\Version-3\%Printer%" /v "Dependent Files" 2^>nul') do (
        if "%%A"== "REG_MULTI_SZ" (
            call :GetFileNames "%%B"
            goto :EOF
        )
    )
    rem Document in results file that printer is not installed on this computer.
    echo Error: %Printer% not installed.>>%ResultsFile%
    
    rem Exit procedure GetPrinterFiles and return to main loop above.
    goto :EOF
    
    rem The file names are passed from procedure GetPrinterFiles in a long string
    rem with \0 as separator between the file names. This long string is split
    rem into individual file names by the FOR loop below. Each file name is
    rem assigned to an environment variable. A case-sensitive comparison is
    rem made between value of this variable having all ".GPD" case-insensitive
    rem removed with unmodified value of this variable. If modified variable
    rem value is equal unmodified variable value, ".GPD" is not present in any
    rem case in file name resulting in writing the file name into the results
    rem file. Otherwise this file containing ".GPD" in any case is ignored.
    
    :GetFileNames
    set "FilesList=%~1"
    for %%F in ("%FilesList:\0=","%") do (
        set "FileName=%%~F"
        if "!FileName:.GPD=!" == "!FileName!" (
            echo !FileName!>>%ResultsFile%
        )
    )
    rem Exit procedure GetFileNames and return to GetPrinterFiles procedure above.
    goto :EOF
    

    Thanks goes to rojo for his answer on separating variable with a symbol into different parts showing me how to process the long string with all the file names separated by \0 by reg on output.