Use DelayedExpansion in nested FOR loops

My objective is to list the local hard disks on PCs and search for specific file on each of them. If found, output the path of the file to a text file that would be named "PCNAME.txt". My expectation is as below:

set filename="abc.exe"
set uncpath="%userprofile%\desktop\"
set fullpath=%uncpath%\%computername%.txt

for /f %%a in ('wmic logicaldisk where "description='Local Fixed Disk'" get Caption ^| find ":"') do (
set letter=%%a
cd %letter%\ 

for /R %%f in (%filename%) do @IF EXIST %%f @echo File Location^(s^) Identified: >> %fullpath% & goto :search

for /R %%f in (%filename%) do @IF EXIST %%f set filenew=%%f & call :trim
echo. >> %fullpath%
exit /b

set filenew=%filenew:"=%
@echo %filenew% >> %fullpath%

The above script works fine when the first FOR loop is removed and current working directory is changed to C:\ drive. But I would want it to run on all local hard drives. After a lot of googling, I guess the approach might be to use DelayedExpansion. I also understand that the goto inside the FOR loop is canceling the loop. But I am not able to fix the script completely.

I would also like to know if it is possible to eliminate the "trim" label altogether and instead double quotes be removed directly under "search" label using DelayedExpansion or whatever. Any help will be appreciated.

2 answers

  • answered 2018-03-13 21:31 jwdonahue

    Just don't ever use multi-line code blocks in your batch scripts.

    @for ... do @call :SubroutineName %%G
    @exit /b 0
    rem Whatever.

    Then do your work in the subroutine without having to worry about all the gotcha's involved in multi-line code-blocks. You'll find that such code is easier to debug with echo on as well.

  • answered 2018-03-13 21:31 Compo

    Here's one method using WMIC and Dir:

    @Echo Off
    Set "filename=abc.exe"
    Set "uncpath=%userprofile%\desktop"
    Set "fullpath=%uncpath%\%computername%.txt"
    Echo File Location(s) Identified:>"%fullpath%"
    Set "_="
    (For /F "Skip=1" %%A In (
        'WMIC LogicalDisk Where "DriveType='3'" Get DeviceID 2^>Nul') Do (
        For /F "Delims=" %%B In ('Dir /B/S/A-D-L "%%A\%filename%" 2^>Nul'
        ) Do Set "_=T" & Echo %%B))>>"%fullpath%"
    If Not Defined _ Del "%fullpath%"

    If you just want the locations without the file name itself, change %%B on the line 11 to %%~dpB.