i had straight forward little batch script. design outline simple enough ... want touch every file 'dropped'.
- there windows short-cut on desktop calls batch (.cmd) script.
- select files windows explorer
- drag-n-drop selection onto either short-cut icon or command file directly.
- the script loops on list of files dropped onto icon.
- the script uses for command call command 1 file @ time.
anyway there several circumstances result strange (to least). worst example infinite loop crashes cmd.exe. here command file. there prints , pauses here can watch behaviour.
@echo off @title touch @echo. cd > z:\$$$\base.tmp set /p base= < z:\$$$\base.tmp @rem @echo ^ folder: %base% @echo ^ input: [%*] @echo. @pause @echo. /d %%x in (%*) ( @echo ^ raw: [%%x] @echo ^ each --^> [%%~x] @echo ^ each --^> [%%~fx] attrib "%%~fx" touch "%%~fx" echo. @pause echo. ) @echo. @echo ^ [done] @echo. @pause the problematic output source of confusion me, see: example 1. put attrib command in because 'tame' system .exe.
when comment-out "touch" command, works attrib most of time. thing can sure file names spaces cause problems. example in echo-ed "each" lines, i've seen examples like:
each --> [z:\tmp\"z:\tmp\c++ recipes.pdf"]"g:\_xfer_\-m"
the first seems problem loop expansion , how deals quotes("). while second appears out of bounds error msys touch.exe command.
there's fish goes on when pass link (short-cut) file script.
i've tried many different versions of both syntax , loop-variable escaping side-step issue. after primary purpose have gui touch command. first question brains trust is:
- what appropriate , loop-variable expansion use this?
as well, since has become mystery ....
- how infinite loop occur , there way prevent it?
- does have link documentation and/or examples of drag-n-drop window?
- how can script show:
working folder ...g:\_xfer_when string: "working folder", not in .cmd script. and, there once version had command:echo working folder:
it helps, put small script called, "drop.cmd" below well. final point, suspect there's bug in msys /gnu command-line handler windows:
- it seem that, when
*argspassed contains string unbalanced quotes -- can go off reservation.
i similar output in example 1, below msys touch , tail commands.
i sign-off. there 1 more thing, consider. have script or diagnostic might use 'unravel' ball-of-wool?
example 1
folder: g:\_xfer_ input: ["g:\_xfer_\00__zip (on d).lnk" g:\_xfer_\#trash.lnk] press key continue . . . raw: ["g:\_xfer_\00__zip (on d).lnk"] each --> [g:\_xfer_\00__zip (on d).lnk] each --> [g:\_xfer_\00__zip (on d).lnk] g:\_xfer_\00__zip (on d).lnk ... g:\_xfer_\00__zip (on d).lnk 1 ... g:\_xfer_\00__zip 2 ... (on working folder ... g:\_xfer_ touch -m -c "g:\_xfer_\-m" working folder ... g:\_xfer_ touch -m -c "g:\_xfer_\-m" : : and crashed stackoverflow!
drop.cmd
@echo off @title %~1 @echo. cd > z:\$$$\base.tmp set /p base= < z:\$$$\base.tmp @rem @echo ^ drop folder: %base% @echo ^ input: [%*] @echo. @pause rem @echo. %%x in (%*) ( @echo ^ raw: [%%x] @echo ^ each --^> [%%~x] @echo. @pause ) @echo. @echo ^ [done] @echo. @pause
getting batch file handle dropped files can difficult. dragged file spaces in name quoted, file special characters (&) without spaces not quoted. lead problems parser handling arguments file using %*.
but taking code jeb' answer , polished @dbenham solve problem of "pretty print windows %path% variable" (thank both), , retrieving arguments %* when called command line (where arguments "should" formed) or %cmdcmdline% (that hold command line used start current cmd instance) when dropped, can like
@echo off setlocal enableextensions disabledelayedexpansion set "var=" rem determine call origin setlocal enabledelayedexpansion call :detectdrop !cmdcmdline! endlocal if not errorlevel 1 goto :dropped :commandline rem invoked command line set "dropped=" if "%~1"=="" goto done set var=%* set "var=%var:"=""%" goto :process :dropped rem invoked explorer set "dropped=1" set "var=%cmdcmdline:"=""%" set "var=%var:*/c """"=%" set "var=%var:*"" =%" set "var=%var:~0,-2%" :process if not defined var goto :done rem adapted dbenham's answer @ [https://stackoverflow.com/a/7940444/2861476] set "var=%var:^=^^%" set "var=%var:&=^&%" set "var=%var:|=^|%" set "var=%var:<=^<%" set "var=%var:>=^>%" set "var=%var: =^ ^ %" set var=%var:""="% set "var=%var:"=""q%" set "var=%var: ="s"s%" set "var=%var:^ ^ = %" set "var=%var:""="%" setlocal enabledelayedexpansion set "var=!var:"q=!" %%a in ("!var:"s"s=" "!") ( if "!!"=="" endlocal rem here have reference passed/dropped element if %%a neq "" echo "%%~fa" ) goto :done :detectdrop cmdcmdline if /i "%~1"=="%comspec%" if /i "%~2"=="/c" exit /b 0 exit /b 1 :done if defined dropped ( pause & exit ) note: sorry, not thoroughly tested. maybe there case make fail.
Comments
Post a Comment