Search code examples
batch-filewmic

how to set % wildacards at the beginning of a wmic inside a for in a batch file


I'm getting a weird behaviour calling wmic inside a batch file, im trying to get the id of a process but when i set %% at the beginning of the string in the like command, it returns random numbers, but when i use them at the end its behaviour is normal

i have tried %%, %, ^%, \% and none of them works. all i have read indicates that i need to escape the % using a %% but i can't make it work at the start of the string

    @echo off
    setlocal EnableDelayedExpansion
    FOR /F %%i in ('dir /b/a-d/od/t:c omcp_*.log') do set "FILENAME=%%i"
    FOR /F "usebackq" %%A IN ('%FILENAME%') DO set "SIZE=%%~zA"
    set commie=0
    IF DEFINED LASTFILENAME (
        IF "%FILENAME%" == "%LASTFILENAME%" (
            if DEFINED LASTSIZE (
                IF "%SIZE%"=="%LASTSIZE%" ( 
->->->                        for /f "UseBackQ tokens=2 delims==" %%f in (`wmic PROCESS WHERE "COMMANDLINE LIKE '%%winlog%%'" GET ProcessID /value ^| find "="`) do set "commie=%%f"
                    echo !commie!
                    IF !commie! equ 0 echo "subir monitor"
                    ) else ( 
                        echo "re subir monitor" 
                )
            )
        )
    )

    set LASTFILENAME=%FILENAME%
    set LASTSIZE=%SIZE%

    REM setx LASTFILENAME FILENAME
    REM setx LASTSIZE SIZE

when i use only the last %% it work and return the id of the winlogon process, and that should happen if i use the start %%, the actual output is random, at least i think are random, numbers; for example:8260,11576,8596 and this is independent of the value that is searched


Solution

  • This is an answer to your specific issue, it does not deal with the other problems with your code, see my comment, or take account of whether, once fixed, the overall task does as you intend it to.

    As well as the problematic line ending issue, also implied in the comments, you need to take account of the fact that when you run the WMIC command, you're doing so with the string winlog included. That means the wmic.exe process CommandLine will match the string winlog too and you'll need to filter against this. It gets more complicated though because the parenthesised WMIC command to For is also run in a separate instance of cmd.exe so the cmd.exe process CommandLine will contain the WMIC command and therefore the string winlog too. You would therefore need to additionally filter against this in your WMIC command as well.

    In summary, of the three ProcessID outputs you've shown in your question, 8260,11576 and 8596 one is for the winlogon process, one the cmd.exe process and the other for the wmic.exe process.

    I'd therefore suggest you change your specifically indicated problematic line to:

    For /F EOL^=P %%A In ('WMIC Process Where "Name<>'cmd.exe' And Name<>'wmic.exe' And CommandLine Like '%%winlog%%'" Get ProcessID 2^>Nul')Do For %%B In (%%A)Do Set "commie=%%B"
    

    I generally prefer to use !=, or this format, Not Name=, but as you've enabled delayed expansion, I decided to steer clear of exclamation points chose the shorter <> alternative.

    Please note that this answer cannot be expected to isolate a specific instance of CommandLine should there be more than one matching process. It also does not account for the possibility that your target CommandLine containing the string winlog could have been run through another instance of cmd.exe. If either of those two are possibilities, then your entire methodology needs a rethink.