我如何获得Windows CMD用于为“播放好'与拖N - 下降 [英] How do I get Windows cmd FOR to 'play-nice' with drag-n-drop
问题描述
我有一个非常简单的小批处理脚本。设计轮廓是很简单的......我想抚摸每一个文件'的跌至的'。
- 有调用批处理(.CMD)脚本在桌面上一个Windows快捷方式。
- 选择与Windows资源管理器 某些文件
- 将正将选区到无论是快捷图标,或直接命令文件。
- 脚本遍历文件列表拖放到该图标。
- 该脚本使用作为命令调用一次命令一个文件。
反正有几种情况,其中的结果很奇怪(至少可以说)。最糟糕的例子是一个无限循环的崩溃的cmd.exe。这里是命令文件。有加印在这里暂停,所以我可以看的行为。
关闭@echo
触摸@title
@回声。
CD> Z:\\ $$$ \\ base.tmp
设置/ p基= LT; Z:\\ $$$ \\ base.tmp
@rem
@echo ^文件夹:%基地%
@echo ^输入:[%*]
@回声。
@暂停
@回声。
针对/ D %%倍In(%*)DO(
@echo ^ RAW:[%% X]
@echo ^每个 - ^> [%%〜X]
@echo ^每个 - ^> [%%〜FX]
ATTRIB%%〜FX
触摸%%〜FX
回声。
@暂停
回声。
)
@回声。
@echo ^ [完成]
@回声。
@暂停
最成问题的输出混乱给我一个来源,请参阅:例1,我把在 ATTRIB ,因为它是一个'驯服'系统的.exe命令。
当您注释掉触命令,外观可与刚 ATTRIB 的最的时间。我可以肯定地说的唯一的事情就是带空格的文件名会导致问题。例如,在回声版的每个的行,我见过类似的例子:
-
每 - > [Z:\\ tmp目录\\Z:\\ tmp目录\\ C ++ Recipes.pdf]
-
G:\\ _ XFER _ \\ - M
首先似乎是在for循环扩张的问题以及如何与引号()的交易。而第二个似乎是一个出界失误与MSYS touch.exe命令。
还有一些鱼的推移,当你通过一个链接(快捷)上的文件的脚本。
我已经尝试了很多不同的版本,无论是语法和循环变量逃逸的侧步的问题。经过我的主要目的是为了有一个GUI touch命令。我对智囊第一个问题是:
- 什么是适当的和循环变量扩展使用此?
同时,由于它已成为一个谜......
<醇开始=2>的工作文件夹...
G:\\ _ _ XFER
当字符串:工作文件夹,这是不是在.CMD脚本。而且,这里曾经是该份命令版本:
回声工作文件夹:
这有帮助,我把一个叫做小脚本,下面还有drop.cmd。作为最后一点,我怀疑有一个错误在Windows中MSYS / GNU命令行处理程序:
- 这似乎是,当
* ARGS
已传递包含不平衡引号的字符串 - 它可以取消预约
我得到类似的输出例1中,下面从MSYS 触摸并从尾命令。
我正要签核。还有一件事,要考虑的问题。有没有人有一个脚本或诊断我可能会使用到'解开'这个的球的羊毛的?
例1
文件夹:G:\\ _ xfer_
输入:[G:\\ _ xfer_ \\ 00__zip(在D).LNKG:\\ _ _ XFER \\#trash.lnk]preSS任意键继续。 。 。 RAW:G:\\ _ xfer_ \\ 00__zip(在D)的.lnk]
每个 - &GT; [G:\\ _ xfer_ \\ 00__zip(在D)的.lnk]
每个 - &GT; [G:\\ _ xfer_ \\ 00__zip(在D)的.lnk]
A G:\\ _ xfer_ \\ 00__zip(在D)的.lnk
所有... G:\\ _ xfer_ \\ 00__zip(在D)的.lnk
1 ... G:\\ _ xfer_ \\ 00__zip
两个... ...(上
工作文件夹...
G:\\ _ xfer_触摸-m -cG:\\ _ XFER _ \\ - M 工作文件夹...
G:\\ _ xfer_触摸-m -cG:\\ _ XFER _ \\ - M
:
:
和最终与计算器坠毁!
drop.cmd
关闭@echo
@title%〜1
@回声。
CD&GT; Z:\\ $$$ \\ base.tmp
设置/ p基= LT; Z:\\ $$$ \\ base.tmp
@rem
@echo ^下降文件夹:%基地%
@echo ^输入:[%*]
@回声。
@暂停
REM
@回声。
在%% X(%*)DO(
@echo ^ RAW:[%% X]
@echo ^每个 - ^&GT; [%%〜X]
@回声。
@暂停
)
@回声。
@echo ^ [完成]
@回声。
@暂停
获取一个批处理文件句柄丢弃的文件可有时困难。任何拖文件在其名字空间将被引用,但有特殊字符的文件(&安培;
),但没有空间将不会被引用。这将导致与解析器使用处理参数文件的问题%*
。
不过从杰布的回答采取 code和的由@dbenham 抛光来解决的问题pretty打印窗口%PATH%
变量的(谢谢你们),并从%提取参数*
从从命令行调用只有当(其中参数的应该的很好形成),或从%CMDCMDLINE%
(持有命令线上使用跌落时,启动电流 CMD
实例),我们可以做这样的事情。
关闭@echo
SETLOCAL ENABLEEXTENSIONS disabledelayedexpansion
集VAR = REM确定呼叫源
SETLOCAL enabledelayedexpansion
来电:detectDrop CMDCMDLINE!
ENDLOCAL
如果没有ERRORLEVEL 1页转到:下降:命令行
从命令行调用REM
将下降=
如果%〜1==转到做
设置VAR =%*
设置VAR =%变种:=,%
转到:过程:下降
从资源管理器中调用REM
设置下降= 1
设置VAR =%CMDCMDLINE:=,%
设置VAR =%变种:* / C=%
设置VAR =%VAR:*=%
设置VAR =%VAR:〜0,-2%。:处理
如果没有定义VAR转到:完成 从dbenham的回答REM改编[http://stackoverflow.com/a/7940444/2861476] 设置VAR =%VAR:^ = ^^%
设置VAR =%VAR:放大器; = ^&安培;%
设置VAR =%VAR:| = ^ |%
设置VAR =%变种:其中= ^&下;%
设置VAR =%VAR:&GT; = ^&GT;%
集VAR =%VAR:= ^^%
组VAR =%VAR:=%
设置VAR =%VAR:=Q%
设置VAR =%变种:=SS%
集VAR =%VAR:^。^ =%
设置VAR =%VAR:=%
SETLOCAL enabledelayedexpansion
设置VAR = VAR:!!Q =
对于一个%%中(VAR!!SS =)做(
如果!!==ENDLOCAL REM下面我们就来传递/下降元素的引用
如果%%一个NEQ,回声〜%% FA )
转到:完成:detectDrop CMDCMDLINE
如果/我%〜1==COMSPEC%%如果/我%〜2==/ C退出/ B 0
退出/ B 1:完成
如果定义了下降(暂停和放大器;出口)
注意:对不起,没有彻底的测试。也许有一些情况下,这将使它失败。
I had a very straight forward little batch script. The design outline is simple enough ... I want to touch every file 'dropped'.
- There is a Windows short-cut on the desktop that calls a batch (.cmd) script.
- Select some files with Windows Explorer
- Drag-n-Drop the selection onto either the short-cut icon or the command file directly.
- The script loops over the list of files dropped onto the icon.
- The script uses the FOR command to call the command one file at a time.
Anyway there are several circumstances where the result is strange (to say the least). The worst example is an infinite loop that crashes cmd.exe. Here is the command file. There are extra prints and pauses here so I can watch the 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.
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 output is a source of confusion to me, see: example 1. I put the attrib command in because it is a 'tame' system .exe.
When you comment-out the "touch" command, the look works with just attrib most of the time. The only thing I can say for sure is that file names with spaces cause problems. For example in the echo-ed "each" lines, I've seen examples like:
each --> [Z:\tmp\"Z:\tmp\C++ Recipes.pdf"]
"G:\_xfer_\-m"
The first seems to be a problem with the FOR loop expansion and how it deals with quotes("). While the second appears to be a out of bounds error with the MSYS touch.exe command.
There's also something fish that goes on when you pass a link (short-cut) file to the script.
I've tried many different versions of both the FOR syntax and the loop-variable escaping to side-step the issue. After all my primary purpose is to have a GUI touch command. My first question for the brains trust is:
- What is the appropriate FOR and loop-variable expansion to use for this?
As well, since it has become a mystery ....
- How does the infinite loop occur and is there a way to prevent it?
- Does someone have a link for documentation and/or examples of FOR with a drag-n-drop with Window?
- How can the script just show:
Working folder ...
G:\_xfer_
When the string: "Working folder", which is NOT in the .cmd script. And, there was once a version that had the command:echo Working folder:
It it helps, I put a small script called, "drop.cmd" below as well. As a final point, I suspect there's a bug in the MSYS /GNU command-line handler for Windows:
- It seem that, When the
*args
that was passed contains a string with unbalanced quotes -- It can go off the reservation.
I get similar output to that in example 1, below from the MSYS touch and from tail commands.
I was about to sign-off. There is one more thing, to consider. Does anyone have a script or diagnostic I might use to 'unravel' this ball-of-wool?
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]
A G:\_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 with a 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
Getting a batch file handle dropped files can be sometimes difficult. Any dragged file with spaces in its name will be quoted, but a file with special characters (&
) but without spaces will not be quoted. This will lead to problems with the parser handling the arguments to the file using %*
.
But taking the code from jeb' answer and polished by @dbenham to solve the problem of "Pretty print windows %path%
variable" (thank you both), and retrieving the arguments from %*
only when called from command line (where arguments "should" be well formed) or from %cmdcmdline%
(that hold the command line used to start the current cmd
instance) when dropped, 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's answer at [http://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=!"
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 thoroughly tested. Maybe there is some case that will make it fail.
这篇关于我如何获得Windows CMD用于为“播放好'与拖N - 下降的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!