Simplest loop to perform actions on x dragged files?

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
pstein
Posts: 108
Joined: 09 Nov 2011 01:42

Simplest loop to perform actions on x dragged files?

#1 Post by pstein » 30 Mar 2014 01:32

Assume I mark in WinExplorer a couple of files and drag them onto a batch file.
The batch file should take each files and perform certain tasks and commands (independently from other files).
After finishing one file it should start over with the next dragged file.

I am searching for the shortest, simplest (and robust) loop definition for this purpose.

The loop should be able to handle blanks and brackets in path/file names.

After all (as last command in batch after loop) it should echo a comment.

Whats the best solution for that?

Peter

foxidrive
Expert
Posts: 6033
Joined: 10 Feb 2012 02:20

Re: Simplest loop to perform actions on x dragged files?

#2 Post by foxidrive » 30 Mar 2014 03:17

Edit: the next line reflects information in the following 8 or so posts

The command line has a length limit of between 2KB and 8KB in different Windows versions (see the posts following this one) so

1) when you drag a file or folder from

c:\users\mark schwazenegger\my files\music\artists\Peter Knopfler\

then each file will have these 66 characters before the filename is added itself.
You can see how this can add up on even longer paths and filenames and so the number of items being dragged to a batch file is limited and changes with the source paths\filenames.

2) Another problem with drag and drop is that a filename\path of c:\music\peter&mary.mp3 will not be quoted and the line will fail at the command line
due to the unquoted & character, and so the batch file behaviour can be unpredictable. This is a bug in Explorer drag-and-drop.

Does your plan change now that you know these things?

Squashman
Expert
Posts: 4114
Joined: 23 Dec 2011 13:59

Re: Simplest loop to perform actions on x dragged files?

#3 Post by Squashman » 30 Mar 2014 06:22

4K in Xp. 8K in Windows 7. I have tested that extensively. Believe we have a thread about it on the forums.

Didnt know about not quoting file names without spaces. I just assumed it quoted every file name you dropped.

aGerman
Expert
Posts: 3763
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Simplest loop to perform actions on x dragged files?

#4 Post by aGerman » 30 Mar 2014 06:59

NOTE See post #33363 for a code with major improvements.

Believe we have a thread about it on the forums.

Yes but I also don't remember where.
I just assumed it quoted every file name you dropped.

No but actually it doesn't matter.

As far as I remember we had to use SHIFT and GOTO rather than %* in a FOR loop to not exceed the length limit in the Batch code. The limits you already told remain valid though.

Code: Select all

@echo off &setlocal
:loop
shift
if exist "%~0" (
  if not exist "%~0\" (
    set "file=%~0"
    call :proc
  )
  goto loop
)
pause
goto :eof


:proc
echo process "%file%" here
goto :eof

Regards
aGerman

Squashman
Expert
Posts: 4114
Joined: 23 Dec 2011 13:59

Re: Simplest loop to perform actions on x dragged files?

#5 Post by Squashman » 30 Mar 2014 07:50

0=1 :)

Squashman
Expert
Posts: 4114
Joined: 23 Dec 2011 13:59

Re: Simplest loop to perform actions on x dragged files?

#6 Post by Squashman » 30 Mar 2014 07:56

aGerman wrote:As far as I remember we had to use SHIFT and GOTO rather than %* in a FOR loop to not exceed the length limit in the Batch code. The limits you already told remain valid though.

Yes. That is how all my batch files are programmed at work.

aGerman
Expert
Posts: 3763
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Simplest loop to perform actions on x dragged files?

#7 Post by aGerman » 30 Mar 2014 08:15

Squashman wrote:0=1 :)

I'm afraid I don't catch that :?

Squashman
Expert
Posts: 4114
Joined: 23 Dec 2011 13:59

Re: Simplest loop to perform actions on x dragged files?

#8 Post by Squashman » 30 Mar 2014 08:55

aGerman wrote:
Squashman wrote:0=1 :)

I'm afraid I don't catch that :?

0 = Batch file name
1 = file names

Vbscript starts at 0. Batch starts at 1.

aGerman
Expert
Posts: 3763
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Simplest loop to perform actions on x dragged files?

#9 Post by aGerman » 30 Mar 2014 09:10

Got it. But SHIFT was first :wink:

Another issue still comes up. When I read foxis answer I thought it doesn't matter if an ampersand is part of the filename. But it fails because the expansion of the parameter stops at the & if it comes in unquoted. No idea why that happens :(

Regards
aGerman

dbenham
Expert
Posts: 2288
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Simplest loop to perform actions on x dragged files?

#10 Post by dbenham » 30 Mar 2014 09:53

jeb has a good explanation and solution here: http://stackoverflow.com/a/5370380/1012053

I think jeb's statement about a ~2048 char limit may be limited to XP. I know I am able to access ~8191 drag&drop characters on Windows 7.

I posted a derivative of jeb's solution that attempts to auto-sense normal vs. drag&drop calls: http://stackoverflow.com/a/8550398/1012053


Dave Benham

aGerman
Expert
Posts: 3763
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Simplest loop to perform actions on x dragged files?

#11 Post by aGerman » 30 Mar 2014 10:14

Thanks Dave.

I didn't read the posts in detail yet. In the meantime I also fiddled with CMDCMDLINE. Thats what I found so far but I think the posts at SO will supersede my attempts :wink:

Code: Select all

@echo off &setlocal

set "first="
set "params=%cmdcmdline:~8,-1%"
setlocal enabledelayedexpansion
for %%i in (!params!) do (
  if "!!"=="" endlocal
  set "file=%%~i"
  call :proc
)
pause
goto :eof


:proc
if not defined first (set "first=1" &goto :eof)
if exist "%file%\" goto :eof

echo process "%file%" here

goto :eof

Regards
aGerman

aGerman
Expert
Posts: 3763
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Simplest loop to perform actions on x dragged files?

#12 Post by aGerman » 30 Mar 2014 11:20

In order to merge the topic with your and jebs discoveries I guess this could be sufficient to process dragged/dropped files:

Code: Select all

@echo off &setlocal DisableDelayedExpansion

setlocal EnableDelayedExpansion
set "params=!cmdcmdline:~,-1!"
set "params=!params:*" =!"

for %%i in (!params!) do (
  if "!!"=="" endlocal
  if not exist "%%~i\" (
    set "file=%%~i"
    call :proc
  )
)

pause
exit


:proc
echo process "%file%" here
goto :eof

Regards
aGerman

EDIT: Forget about it. Also this technique doesn't solve the problems caused by delimiters like ';' ',' '=' where the '=' is a character I can't imagine a reasonable workaround :(

foxidrive
Expert
Posts: 6033
Joined: 10 Feb 2012 02:20

Re: Simplest loop to perform actions on x dragged files?

#13 Post by foxidrive » 30 Mar 2014 19:23

Squashman wrote:4K in Xp. 8K in Windows 7. I have tested that extensively. Believe we have a thread about it on the forums.


I edited my post to reflect the info - jeb's linked post above seems to indicate that drag and drop has had a different limit.

jeb
Expert
Posts: 918
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: Simplest loop to perform actions on x dragged files?

#14 Post by jeb » 31 Mar 2014 00:26

I suppose one solution could be the technic from 'Pretty print' windows %PATH% variable - how to split on ';' in CMD shell.
The main idea is to split the line on spaces, but to avoid to split on spaces inside filenames, the inner spaces are escaped different than the spaces outside of quotes.

jeb

pstein
Posts: 108
Joined: 09 Nov 2011 01:42

Re: Simplest loop to perform actions on x dragged files?

#15 Post by pstein » 31 Mar 2014 01:14

Ok thank you so far.

The limit of 8K should be acceptable in general.
Only in rare occasions the length will be exceeded.

How can I check whether the cmdline length is above the max limit?
I prefer not to use your tricky SHIFT and GOTO solution but keep it in short, more human readable ol' style.

Moreover what makes me anxious is your tiny hint about the "&" in file names (and I guess brackets as well).

So I tried it out immediately and found file names with & and () quoted:

"D:\somefiles\peter&mary.txt" "D:\somefiles\peter+(mary).txt"

So whats the problem?

If there is really a problem: Can I somehow tell DOS to automatically mask at first such critical chars to

"D:\somefiles\peter^&mary.txt"
"D:\somefiles\peter+^(mary^).txt"

That should work at least

Peter

Post Reply