1

I've written a video convertion batch, where the user can simply drag and drop his videos from any disk or partition onto the batch, after which the converted video will be saved on a particular location on a particular disk.

The code looks like this

@echo off
%~d0
cd %~p0
for %%f in (%*) do ...
pause

The actual problem lies with (%*).
When my file has a closing round bracket in its name, the batch won't work. To fix this, I used ("%*"), but this doesn't work with files that have spaces in their names, or with multiple files.
I also tried with (%~*) but that is invalid.

After some research I noticed, that when I drop multiple files on the batch with the names file(test) and file test, %* resolves to

file(test) "file test"

Which means that a filename may have quotation marks, or not...

My question is: How do I deal with this?
Ideally, I would like %* to resolve to "file(test)" "file test" (both names wrapped around quotes)

Nolonar
  • 5,962
  • 3
  • 36
  • 55
  • 1
    Side comment: note that you could use `pushd %~dp0` instead of `%~d0` + `cd %~p0`. Side benefit is you can do a `popd` at the end if you want to get back to your original folder. – Nate Hekman Mar 11 '13 at 19:23
  • Alternatively to `pushd`, you could use `cd /d %~dp0`. – Andriy M Mar 11 '13 at 20:44
  • Possible duplicate of [Batch file Copy using %1 for drag and drop](https://stackoverflow.com/questions/14786623/batch-file-copy-using-1-for-drag-and-drop) – phuclv Aug 16 '18 at 11:23

1 Answers1

5

Instead of using a for loop, you could call a subroutine with each parameter, one at a time.

:nextArgument
set arg=%~1
if not defined arg goto :eof
call :processFile "%arg%"
shift
goto nextArgument

:processFile
set file=%~1
echo "%file%"
:: do your processing here
goto :eof

This will process each space-separated argument (but quoted arguments can include spaces) one at a time, passing them to the processFile routine. I use %~1 to remove quotes from the argument first, then add quotes back in when calling processFile. That way I know when I get to processFile that everything has quotes around it.

Nate Hekman
  • 6,507
  • 27
  • 30
  • +1 Interesting solution. I'll wait for other answers before accepting, though (hope you understand). – Nolonar Mar 11 '13 at 19:36
  • I decided to accept your answer ahead of time, because I'm fairly impatient ;) but also, because I learned a lot from this answer and my code ended up being more readable than my original code (because `for` forced me to put all my calls on a single line) – Nolonar Mar 11 '13 at 19:58
  • @Nolonar: It probably wasn't `for` that forced you to put all your calls on the same line but likely your unawareness of the multi-line syntax. Use brackets (`()`) around the loop body. That will allow you to put the loop body's individual commands on their own lines, something like this: `for ... do (` `command1` `command2` ... `)` `...` (the closing `)` can go on a separate line). Still, using a `goto` loop instead of a `for` has its benefits too and learning this technique definitely won't hurt. – Andriy M Mar 11 '13 at 20:56
  • 1
    @Nate: It is often a good idea to adding `"` around assignments: `set "arg=%~1"`. That will allow you to escape characters that are allowed in names and yet have special meaning in batch files (e.g. `&`). – Andriy M Mar 11 '13 at 20:59
  • 1
    +1, @Nate Like Andriy M suggest, you should enclose it into quotes, and don't expand `arg` in the call, as then you got problems with carets `^`, better access it via delayed expansion later by the varname. – jeb Mar 11 '13 at 21:39