How to get Windows cmd FOR for "play-nice" using drag-n-drop

I had a very simple small batch of script. The outline of the design is quite simple ... I want to touch every file "dropped."

  • There is a short Windows clipping on the desktop that calls the package (.cmd) script.
  • Select some files in Windows Explorer
  • Drag-n-Drop selection on short cut icon or batch file directly.
  • The script moves through the list of files discarded by the icon.
  • The script uses the FOR command to invoke the command one file at a time.

In any case, there are several circumstances when the result is strange (at least). The worst example is an infinite loop that causes cmd.exe error. Here is the batch file. There are additional prints and pauses, so I can observe the behavior.

@echo off @title touch @echo. cd > z:\$$$\base.tmp set /p base= < z:\$$$\base.tmp @rem @echo ^ folder: %base% @echo ^ INPUT: [%*] @echo. @pause @echo. for /d %%x in (%*) DO ( @echo ^ RAW: [%%x] @echo ^ each --^> [%%~x] @echo ^ each --^> [%%~fx] attrib "%%~fx" touch "%%~fx" echo. @pause echo. ) @echo. @echo ^ [done] @echo. @pause 

The most problematic conclusion is a source of confusion for me, see: Example 1. I entered the attrib command because it is a “manual” .exe system.

When you comment out the touch command, appearance only works with an attribute in most cases. The only thing I can say for sure is that file names with spaces cause problems. For example, in the highlighted “ each ” lines I saw examples such as:

  • each --> [Z:\tmp\"Z:\tmp\C++ Recipes.pdf"]
  • "G:\_xfer_\-m"

The first problem is related to the extension of the FOR loop and how it relates to quotation marks ("). Although the second seems to be an error outside the MSYS touch.exe command.

There is also something that happens when you pass a link file (shortened) to a script.

I tried many different versions of both the FOR syntax and the loop escape sequence to fix the problem. In the end, my main goal is to have a GUI interface command. My first question for confidence in the brain is:

  • What is needed for this to expand the FOR variable and the loop?

Also, as it has become a mystery ....

  1. How does an infinite loop happen and is there a way to prevent it?
  2. Does anyone have a link to documentation and / or FOR examples using drag-n-drop with a window?
  3. How can I show the script: Working folder ... G:\_xfer_ When the line: "Working folder", which is NOT in the .cmd script. And once there was a version with the command: echo Working folder:

This helps, I also added a little script, "drop.cmd". As a final point, I suspect there is an error in the MSYS / GNU command line handler for Windows:

  • It seems that when the *args that was passed contains an unbalanced quote string, it can leave the reservation.

I get a similar output in example 1 below from the MSYS touch commands and from the tail .

I was about to sign. There is one more thing to consider. Does anyone have a script or diagnostics that I can use to "unravel" this ball?

example 1

  folder: G:\_xfer_ INPUT: ["G:\_xfer_\00__zip (on D).lnk" G:\_xfer_\#trash.lnk] Press any key to 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] AG:\_xfer_\00__zip (on D).lnk all ... G:\_xfer_\00__zip (on D).lnk one ... G:\_xfer_\00__zip two ... (on Working folder ... G:\_xfer_ touch -m -c "G:\_xfer_\-m" Working folder ... G:\_xfer_ touch -m -c "G:\_xfer_\-m" : : 

And eventually crashed using 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. for %%x in (%*) DO ( @echo ^ RAW: [%%x] @echo ^ each --^> [%%~x] @echo. @pause ) @echo. @echo ^ [done] @echo. @pause 
0
source share
1 answer

Obtaining a batch file descriptor with dropped files can sometimes be difficult. Any dragged file with spaces in its name will be specified, but a file with special characters ( & ), but without spaces, will not be quoted. This will lead to problems with the parser processing the arguments in the file using %* .

But taking the code from jeb's answer and polished @dbenham to solve the problem “Enough print windows %path% variable” (thank you both) and extract arguments from %* only when called from the command line (where the arguments should be) or %cmdcmdline% (which hold the command line used to start the current cmd instance) when we delete, we can do something 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 from command line set "dropped=" if "%~1"=="" goto done set var=%* set "var=%var:"=""%" goto :process :dropped rem Invoked from 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 from dbenham answer at [/questions/28787/pretty-print-windows-path-variable-how-to-split-on-in-cmd-shell/210914#210914] 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=!" for %%a in ("!var:"S"S=" "!") do ( if "!!"=="" endlocal rem Here we have a reference to the 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 fully verified. Perhaps there is a case that will make him fail.

+2
source

Source: https://habr.com/ru/post/1269112/


All Articles