1

I am trying to write a batch script that does the following:

When a folder is drag-and-dropped onto the batch script, it processes every file in that folder.

I am running into a problem with a certain filenames that contain exclamation marks. e.g.:

!.txt or !!!.txt

For now, I am simply trying to rename the file to demonstrate the issue:

@echo off

SetLocal EnableDelayedExpansion
set folder=%~1
set count=0

for /r "%folder%" %%G in (*) do (
    set fullpath=%%G
    set fileExtension=%%~xG
    call :processFile
)
goto end

:processFile
    echo "fullpath = %fullpath%"
    echo "fileExtension = %fileExtension%"

    rename "%fullpath%" "temporary_filename_500%fileExtension%"

    set /a count+=1
echo.
    goto :eof

:end

echo "%count% files processed."

pause

It gives me the error "The system cannot find the file specified." However, it works if I change the filename to something simple like "test.webm" How can I make the script more robust?

sdMarth
  • 521
  • 1
  • 8
  • 15
  • 1
    With `SetLocal EnableDelayedExpansion`, you should change some `%` to `!`. Check `setlocal /?` for details. Also when you are testing things, comment or remove `@echo off`. – Til Mar 03 '19 at 06:45
  • Why do you have enabled delayed environment variable expansion? You don't use it and it is not necessary with your code to enable it. The command line `set fullpath=%%G` is parsed twice with delayed expansion resulting in interpreting on second parsing of the command line every `!` in file name as begin/end of an environment variable of which value is referenced delayed. See [How does the Windows Command Interpreter (CMD.EXE) parse scripts?](https://stackoverflow.com/questions/4094699/) – Mofi Mar 03 '19 at 08:33
  • One more hint: Don't use `echo.` to output an empty line. See DosTips forum topic: [ECHO. FAILS to give text or blank line - Instead use ECHO/](https://www.dostips.com/forum/viewtopic.php?f=3&t=774) for the reason and alternatives like `echo/` or `echo(`. – Mofi Mar 03 '19 at 08:35
  • 1
    Just remove `EnableDelayedExpansion` part from this line: `SetLocal EnableDelayedExpansion` – Aacini Mar 03 '19 at 12:38

1 Answers1

1

I don't see that you are using somewhere delayed expansion. So, either disable it with setlocal DisableDelayedExpansion in the start of your batch file or just remove it by removing line setlocal EnableDelayedExpansion.

However, if you want to keep it, do:

@echo off

SetLocal EnableDelayedExpansion

rem Code above (^^) if exists.

Setlocal DisableDelayedExpansion

set "folder=%~1"
set "count=0"

for /R "%folder%" %%G in (*) do (
    set "fullpath=%%~fG"
    set "fileExtension=%%~xG"
    call :processFile
)
goto end

:processFile
echo "fullpath = %fullpath%"
echo "fileExtension = %fileExtension%"

ren "%fullpath%" "temporary_filename_500%fileExtension%"

set /a "count+=1"
echo/
goto :eof

:end
echo "%count% files processed."
pause
setlocal EnableDelayedExpansion

rem Your code below with active delayed expansion:

Note that:

  • You should always quote the variable name and the value in the set command like set "var=value" and in set /a like set /a "var+=1", etc.; see set /? for more information.
  • To find the full path of a file/folder for sure in a for loop, use the f modifier, like %%~fG.
  • Mentioned by Mofi here: don't use echo.; use echo/ for better practice.

See also the Phase 5 (Delayed Expansion) of this answer about how batch files are interpreted.

double-beep
  • 5,031
  • 17
  • 33
  • 41
  • Are you happy with your answer? In my opinion there is a problem with your provided code and some issues with the accompanying body text. All you needed to do if you wanted to boost your point score was to repeat the comments that were already made, i.e. remove the unnecessary statement which enables delayed expansion. Optionally you could have advised on the recommended syntax for setting variables. – Compo Mar 03 '19 at 14:05