1

I am trying to automate with a very simple batch file the editing of PDF titles. I want to be able to drag and drop a series of files and have cmd run exiftool for each one. After running the command, I wanted to display a message asking whether the edit went succesfully or not, in the first case I would delete the _original backup files created form exiftools and in the second case I would restore them. This is what I wrote:

:renaming
if "%~1" == "" goto:done
"C:\Users\Alessio\Desktop\Programmazione\Exiftools\exiftool.exe" "-title<${filename;s/.[^.]*$//}" "%~1"
shift
goto:renaming

:deleteOriginals
if "%~1" == "" goto:end
"C:\Users\Alessio\Desktop\Programmazione\Exiftools\exiftool.exe" -restore_original "%~1"
shift
goto:deleteOriginals

:restoreOriginals
if "%~1" == "" goto:end
"C:\Users\Alessio\Desktop\Programmazione\Exiftools\exiftool.exe" -delete_original "%~1"
shift
goto:restoreOriginals

:done
shift /1
choice /C YN /M "I file sono stati rinominati correttamente?" && goto:deleteOriginals || goto:restoreOriginals

:end
pause

It appears that once I cycle once through the parameters that I got from the drag and drop, I can't just call shift /%1 to go back to the start. How would I do this? I tried to fiddle around with the set command with little luck. If batch isn't able to do this I was thinking that maybe I could have exiftool create a text file with all the paths and have the cmd load the arguments from there and delete it in the end. Thanks in advance

nidafjoll
  • 11
  • 3
  • 1
    When I understand it correctly, you want [conditional executing](https://ss64.com/nt/syntax-redirection.html) (see `&&` and `||`) – Stephan Nov 17 '20 at 21:10
  • I have followed the recommendation (editing my question) but it still gives the same problem. Everything works well until after the choice statement, when it goes to the :deleteOriginals or :restoreOriginals section the cmd displays `if "" == "" goto:end` and the program ends without executing the desired command – nidafjoll Nov 17 '20 at 21:58
  • 1
    keep in mind: `goto` doesn't "undo" `shift`. You are supposed to do the conditional executing within the very first loop: `exiftool ... && delete original || restore original` and skip the rest of the code. – Stephan Nov 17 '20 at 22:25
  • Aah I see what you mean... but I need to make it so that delete original and restore original depend on user input (choice command). It's not conditional upon whether exiftool ran succesfully or not (I'm not even sure it outputs a true/false value). I wanted to be able to do so in a single batch file, without having to create 2 more for the deleteOriginal and restoreOriginal – nidafjoll Nov 17 '20 at 22:47
  • Something else that comes to mind: exiftool is able to handle multiple arguments. Is there a way to make it so that drag and dropping will display each file as an argument on the same line? e.g. `exiftool "C:\...\fileA.pdf" "C:\...\fileB.pdf" "C:\...fileC.pdf"` I feel like that would make everything simpler – nidafjoll Nov 17 '20 at 22:48
  • `%*` is "all parameters". Keep in mind, the maximal length of a command line is shortly above 8100 chars. If there are too many drag-dropped files, you may exceed that limit (which will just cut off the rest - probably somewhere in the middle of a parameter). But your current approach has the same limitation. – Stephan Nov 18 '20 at 08:50
  • Yeah I read about that. It won't be a problem for what I need to do, as I won't drag and drop that many files (I'll just drag a folder and feed that to exiftool). Still, do you have any suggestion? Maybe assign the arguments to a variable each and then call the variables? I don't know – nidafjoll Nov 18 '20 at 11:11

1 Answers1

0

I have managed to make it work by removing the loops. Still open to suggestions about going down that path, but this seems to work:

"C:\Users\Alessio\Desktop\Programmazione\Exiftools\exiftool.exe" "-title<${filename;s/.[^.]*$//}" %*

choice /C YN /M "I file sono stati rinominati correttamente?"
if "%errorlevel%" == "1" goto:deleteOriginals
if "%errorlevel%" == "2" goto:restoreOriginals

:deleteOriginals
"C:\Users\Alessio\Desktop\Programmazione\Exiftools\exiftool.exe" -k -delete_original %*
exit

:restoreOriginals
"C:\Users\Alessio\Desktop\Programmazione\Exiftools\exiftool.exe" -k -restore_original %*
exit

In place of the if statements I tried using this iteration but it didn't work for some reason, can't figure out why:

choice /C YN /M "I file sono stati rinominati correttamente?" && goto:deleteOriginals || goto:restoreOriginals
nidafjoll
  • 11
  • 3
  • 1
    `&&` recognises an exit code of zero, but `choice` sets it to one, two, etc., depending on the user input, so it is always `||` that comes in; that is why you need the `if` conditions… – aschipfl Nov 17 '20 at 23:34
  • 1
    In addition, regard that argument handling with drag-and-drop onto batch-files is terribly implemented, because file paths become quoted only when it contains spaces, but any other special characters (like `&`, `^`, `(`, `)`, or `,`, `;`, `=`) do not become protected by quotes… – aschipfl Nov 17 '20 at 23:41
  • Is there any way to work around this? Or is batch just the wrong tool for the job? – nidafjoll Nov 18 '20 at 11:13
  • There are indeed work-arounds – refer to [Drag and drop batch file for multiple files?](https://stackoverflow.com/a/5370380) and [Handling ; (semi-colon) in filenames with this drag and drop routine](https://stackoverflow.com/q/59930635)… – aschipfl Nov 18 '20 at 11:43