Home > Blockchain >  Batch Recursively Launch Specific .exe
Batch Recursively Launch Specific .exe

Time:08-14

In windows I have a batch file, named the same as a folder in its current directory.

I am trying to recursively launch a specific .exe file that is a few folders deep in the above mentioned folder.

I am trying:

set "NAME=DRAGON QUEST XI S.exe"
for /R "%~n0\" %%I in ("%NAME%") do if exist "%%I" start "" /WAIT "%%I"

But that is trying to launch DRAGON.exe, then QUEST.exe, then XI.exe then S.exe and I don't understand why.

I think it will have something to do with quotes, but have tried adding/removing them from everywhere I could see and no luck.

Adding a wildcard to ("%NAME%*") works, but could be troublesome if there is more than one .exe that starts with DRAGON.

CodePudding user response:

What you have encountered is caused by something that I consider a terrible design flaw of the for /R loop and expansion of its meta-variable together with the ~-modifiers.

Create the following batch file and execute it:

@for /R "%~dp0." %%I in (foo bar "foo bar" "foo bar?") do @(
    echo/
    echo Modifier '~nx': %%~nxI
    echo No modifiers  : %%I
    echo Modifier '~'  : %%~I
    echo Modifier '~f' : %%~fI
    echo '~' and quoted: "%%~I"
)

The output will be this, given that there are two files foo bar and foo barS available in the directory of the batch file:

Modifier '~nx': foo
No modifiers  : D:\test dir\foo
Modifier '~'  : D:\test dir\foo
Modifier '~f' : D:\test dir\foo
'~' and quoted: "D:\test dir\foo"

Modifier '~nx': bar
No modifiers  : D:\test dir\bar
Modifier '~'  : D:\test dir\bar
Modifier '~f' : D:\test dir\bar
'~' and quoted: "D:\test dir\bar"

Modifier '~nx': "foo bar"
No modifiers  : D:\test dir\"foo bar"
Modifier '~'  : D:\test dir\"foo bar"
Modifier '~f' : D:\test dir\"foo bar"
'~' and quoted: "D:\test dir\"foo bar""

Modifier '~nx': foo bar
No modifiers  : D:\test dir\foo bar
Modifier '~'  : D:\test dir\foo bar
Modifier '~f' : D:\test dir\foo bar
'~' and quoted: "D:\test dir\foo bar"

Modifier '~nx': foo barS
No modifiers  : D:\test dir\foo barS
Modifier '~'  : D:\test dir\foo barS
Modifier '~f' : D:\test dir\foo barS
'~' and quoted: "D:\test dir\foo barS"

It seems that the ~-modifiers (which remove potential surrounding quotation marks) are applied too late, namely after preceding an iterated item with the absolute root path. A standard for loop does not precede anything, so the problem cannot arise and the ~-modifiers may see a quoted string (remove /R "%~dp0." from the batch file, run it again from its parent directory and check quotation in the output).

The line that reflects our situation is the one '~' and quoted: "D:\test dir\"foo bar""; due to its wrong quotation, the command parser unintentionally recognises two different tokens "D:\test dir\"foo and bar"" in the expanded value of "%%~I".


To return to your code, there are the following options to work around the bad behaviour of for /R:

  1. Append a wildcard (best to use ? since it matches just a single character and therefore reduces the chance of matching unwanted items) and then recheck the name of the iterated item:

    set "NAME=DRAGON QUEST XI S.exe"
    for /R "%~n0" %%I in ("%NAME%?") do (
        if /I "%%~nxI"=="%NAME%" (
            if exist "%%I" (
                ECHO start "" /WAIT "%%I"
            )
        )
    )
    
  2. Let dir /S return the matching file(s) and use for /F to process its output:

    set "NAME=DRAGON QUEST XI S.exe"
    for /F "delims=" %%I in ('dir /S /B /A:-D-H-S "%~n0\%NAME%"') do (
        if exist "%%I" (
            ECHO start "" /WAIT "%%I"
        )
    )
    
  • Related