Drag & drop files to batch

December 24, 2009 at 03:46:43
Specs: Windows XP
I've written a batch to let user drag & drop 1-5 files to be processed. It will first list all the files dropped in with path & full filenames, then start the process. The first part of the script is listed as follows:

@echo off&&setLocal EnableDelayedExpansion
if [%1]==[] (
echo Please drag and drop files to the icon
pause&&goto :eof)
if not [%6]==[] (
echo Too many files
pause&&goto :eof)
cls
echo "%~nx0" is going to process following files:
echo.
FOR /F "delims=" %%Y in (%*) do if not [%%~fY]==[] echo %%~fY
:::FOR /F "delims=" %%Y in ("%*") do if not [%%~fY]==[] echo %%~fY


echo.
echo Press any key to start or CTRL-C to quite
pause > nul

:start

It works fine until I try a file with round brackets ( ) e.g. "test_with_(bracket).ts", the batch fails to process and close the command prompt window. So I replace the for-loop line with the line marked with :::(adding quotes around %*), it works fine but fails again when dropped in filename with round brackets and space e.g. "test with space and (bracket).ts".
That means,
1st version works fine with "test with space and (bracket).ts" but fails with "test_with_(bracket).ts".

2nd version works fine with"test_with_(bracket).ts" but fails with "test with space and (bracket).ts".


How can I modify the script to accept both types of filename?
Thanks in advance!


See More: Drag & drop files to batch

Report •

#1
December 25, 2009 at 04:58:57
I would try replacing :

if not [%%~fY]==[] echo %%~fY

with

if not "%%~fY"=="" echo %%~fY

With both of the different solutions you have
(%*)
("%*")


Report •

#2
December 25, 2009 at 06:28:40
Thanks tvc.
I've tried your suggestion, I even try replacing the line with
if not %%~fY.==. echo %%~fY
all with the same result as the previous.

Report •

#3
December 25, 2009 at 19:59:28
The problem is this: File names with spaces automatically
get double quoted, those without don't. The brackets kill
the for loop because the cmd processor can't tell what is
the for loop and what is the data.

You can either use:

for %%a in ("%~1" "%~2" "%~3" "%~4" "%~5" "%~6") do echo %%~fa

Or something like this:

set "arg=%*"
set "arg=%arg:)=^)%"
set "arg=%arg:(=^(%"
for %%a in (%arg%) do echo %%~fa


Batch Variable how to


Report •

Related Solutions

#4
December 26, 2009 at 06:16:31
Thanks Judago! You solve my mystery. Now, I know why file names with and without spaces and brackets behave so different. Both solutions work fine, but the 2nd solution is more suitable for me. Since my batch only accepts files with ".ts" extension, there is one more checking in my batch to see whether the input format is valid. My original script is:
FOR %%B IN (%*) DO if /i not [%%~xB]==[.ts] echo %%~xB is an invalid format&pause&goto :eof
If I apply the 1st method,
FOR %%B IN ("%~1" "%~2" "%~3" "%~4" "%~5") DO if /i not [%%~xB]==[.ts] echo %%~xB is an invalid format&pause&goto :eof
the batch will only work fine when I drag & drop 5 files to it. If I drop 1 ts file, it will echo " is an invalid format" because it will treat as I drop some files without file extension(%~2 to %~5 are empty).

Report •

#5
December 26, 2009 at 12:32:02
might just add an if:
if "%%B" neq "" (
before testing the extension .ts

Report •

#6
December 30, 2009 at 02:05:08
Thanks nbrane. I've tried your suggestion, it doesn't work either, so I will stick with Judago's 2nd method. However I encounter similar problems when trying with filenames contain special characters. These special characters include !^&=;, which are valid in Windows filename system but with special functions in batch scripting.
I've revised the batch script as follows:
@echo off&&setLocal EnableDelayedExpansion
if [%1]==[] (echo Please drag and drop files to the icon&pause&goto :eof)
if not [%6]==[] (echo Too many files&pause&goto :eof)
set "arg=%*"
set "arg=%arg:)=^)%"
set "arg=%arg:(=^(%"
set "arg=%arg:!=^!%"
set "arg=%arg:;=^;%"
set "arg=%arg:,=^,%"
set "arg=%arg:==^=%"
set "arg=%arg:&=^&%"
set "arg=%arg:^=^^%"
FOR %%B IN (%arg%) DO (
if /i not [%%~xB]==[.ts] echo %%~xB is an invalid format&pause&goto :eof
)
cls
echo "%~nx0" is going to process following files:
echo.
for %%a in (%arg%) do echo %%~fa
for %%Y in (%arg%) do if not [%%~fY]==[] echo %%~fY
echo.
echo Press any key to start or CTRL-C to quite 
pause > nul
:start

I've tried the following filenames:
"test!.ts" "test;.ts" "test,.ts" "test1, test2.ts" "test^.ts" "test&.ts" "test=.ts" "test1 & test2.ts"
All fail to echo the correct filename.
How should I modify the script to deal with filenames with these special characters (!^&=;,)?

One additional question, is it possible to use 1 for-loop to handle 2 set of variables?
1st set of variables is the filenames drag and drop to the batch,
2nd set of variables is the new filenames enter by user.
In the latter part of my batch, I will use a command-line program to convert the input files to new format with new filenames (assigned by the user). The C/L program needs the above two sets of variables as parameters.
For ease of testing, I try to echo 2 sets of variables at the same line to see whether the script works but it fails to do so (unable to echo %Name1% to %Name5%).


:inputname
cls
set cc=0
FOR %%A IN (%arg%) DO IF NOT [%%~A]==[] (
set /a cc+=1
set /p Name!cc!=Enter the new name of "%%~nA": 
)
set dd=0
FOR %%B IN (%arg%) DO IF NOT [%%~B]==[] (
set /a dd+=1
echo %%~fB will be converted to !Name%dd%!
)

Any help is appreciated.


Report •

#7
December 30, 2009 at 04:31:34
I've been looking into this and have come to the conclusion that, in xp at least, this simply won't work.

One of the main reasons is that arguments can be separated a semicolon, comma, space, equals sign or tab. Since filenames without spaces aren't quoted it's possible to have a single filename split up into multiple arguments and lose these characters in the process.

Take the example of a file name with an ampersand and no spaces, everything after and including the ampersand are lost! Not even split into multiple arguments, completely lost!

Simply put I think you either have to find another way of getting filenames or switch to another language.


Batch Variable how to


Report •

#8
December 30, 2009 at 06:23:30
Thanks Judago.
Fortunately, it is rather rare to have filename containing these special characters. However, it is quite often to have filename with space and round brackets. You've already helped me to solve it. I wonder if vbscript is much better in handling filenames.
I'm also curious to know if it is possible to use one for-loop to handle 2 sets of variables as I stated in my 2nd question.

Report •

#9
December 30, 2009 at 07:14:28
You will need a second loop because of the nature of
expansion(see the link in my sig), but it need not be seperate.

A for /l loop could also be used after "cc" has the highest
number, but could not be nested like below.

:inputname
cls
set cc=0
FOR %%A IN (%arg%) DO IF NOT "%%~A"=="" (
    set /a cc+=1
    set /p Name!cc!=Enter the new name of "%%~nA": 
    for %%B in (!cc!) do (
        echo %%~fA will be converted to !Name%%B!
    )
)


Batch Variable how to


Report •

#10
January 1, 2010 at 07:52:20
aqua: I wonder if vbscript is much better in handling filenames.
It is.
For Each a In WScript.Arguments
  WScript.Echo """" & a & """"
Next


Report •

Ask Question