Board logo

标题: [文件操作] 其实CMD原生支持操作含有多种形式特殊字符的文件和目录! [打印本页]

作者: watermark    时间: 2012-1-22 23:58     标题: 其实CMD原生支持操作含有多种形式特殊字符的文件和目录!

CMD原生就支持解析多种特殊字符,只要是合法的文件(夹)名称,批处理都能正确处理,无需修改系统文件和注册表,不必投机取巧和钻漏洞。

如下图,把含有任意 =,;&^~@#$%()' 字符的文件拖放至批处理的图标上, 生成一个新的文件夹,绝无任何PS:

代码迟一些再公布。

祝大家新年快乐!
作者: find    时间: 2012-1-23 00:20

虽然不知道楼主在说什么,但是感觉地球人都知道的样子。
作者: watermark    时间: 2012-1-23 00:42

本帖最后由 watermark 于 2012-1-23 17:33 编辑

回复 2# find
http://www.bathome.net/viewthread.php?tid=7509
你写一个看看。
感觉你都没看清楚。
作者: applba    时间: 2012-1-23 01:16

楼主有兴趣可以测试一下xp系统下的
作者: watermark    时间: 2012-1-23 02:00

回复 4# applba

特意进入 XP SP3 的 PE 里测试了一下,结论一样!
Win98 和 Win3.1 我就不测了,其实能否解析特殊字符跟系统版本无关。
作者: find    时间: 2012-1-23 12:26

回复 3# watermark


那个帖子是要求多个文件拖到cmd窗口后获取每一文件的完整路径,跟你这个有何关联?
作者: BillGates    时间: 2012-1-23 12:33

晕啊,感觉很厉害的样子,楼主公布代码吧。
作者: defanive    时间: 2012-1-23 15:03

不知道LZ什么意思
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. set /p pth=
  4. md "!pth!"
  5. pause
复制代码

作者: cyxgg    时间: 2012-1-23 15:29

回复 8# defanive


    你不是在bat吧发布魔塔的那个?
作者: defanive    时间: 2012-1-23 15:51

回复 9# cyxgg
是的,在这里发了,然后转发去贴吧的
作者: aries215    时间: 2012-1-23 17:24

回复 8# defanive
是拖至批处理的图标上执行.
作者: watermark    时间: 2012-1-23 17:40

回复 8# defanive

不知道你是什么意思, 看看你8楼的代码执行结果吧:

今天是春节, 不是愚人节.
作者: watermark    时间: 2012-1-23 18:51

本帖最后由 watermark 于 2012-1-23 19:44 编辑

回复 8# defanive

Win2008 不能拖入文件至批处理窗口, 而且你的是在同级目录内生成同名文件夹!
我的批处理是没有"/p"的, 也不存在这些问题.
作者: CrLf    时间: 2012-1-23 20:43

本帖最后由 CrLf 于 2012-1-24 19:08 编辑

试写两种思路…
  1. @echo off&setlocal enabledelayedexpansion
  2. set str=!cmdcmdline:*^" =!
  3. set str= !str:^"=!
  4. for %%a in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do set "str=!str: %%a:=" "%%a:!"
  5. for /f "delims=" %%a in (^"!str:~2!"") do endlocal&echo %%a
  6. pause
复制代码
  1. @echo off&setlocal enabledelayedexpansion
  2. set str=!cmdcmdline:*" =!
  3. for %%a in (^^ ^& ^, ^; ^( ^) ) do set "str=!str:%%a=^%%a!"
  4. if !str:~-1!==^" set "str=!str:~,-1!"
  5. (endlocal
  6. for /f "delims=" %%a in ("%str:""="%") do echo %%a)
  7. pause
复制代码
修改两个不严谨的地方。
方案一对付拖动文件到图标时应该是比较通用的,但是难以应付传递参数的情况。因等号无法直接替换,故在方案二中未对其进行转义处理,其实思路和旧帖中qzw的方案类似,如他当时所言,逐字转义确实是比较稳妥可靠的办法,所得的结果也比较通用。
作者: watermark    时间: 2012-1-23 21:09

本帖最后由 watermark 于 2012-1-23 21:28 编辑

回复 14# CrLf

大哥, 你这没有任何结果的, 自己没测试过.

我还是建议大家贴图就好了, 测试通过的才贴代码.

我是说原生支持, 但并非那么普通.
作者: CrLf    时间: 2012-1-23 23:33

测试过才发的,既然实现 echo 了,改一下不就是 md 了吗?不过楼主貌似有不一样的思路,很感兴趣,期待…
作者: defanive    时间: 2012-1-24 01:52

回复 12# watermark
我也测试过了,你估计代码都没看吧
我md的时候已经加过一次双引号了,你输入的时候把双引号去掉不就是了,或者直接把我代码里面的双引号去掉不就好了
作者: watermark    时间: 2012-1-25 10:25

回复 14# CrLf

我的全程无需转义,对各种合法的文件名都能轻松处理,所以才说“原生支持”。
关键是开头 set 那一句吧, 当然也不像楼上那样的才两行命令。

伟大的斑竹们啊,请饶恕我继续故弄玄虚一把呀。。。
作者: defanive    时间: 2012-1-25 11:11

回复 18# watermark
我那个代码也可以实现你的效果,有简单的为什么不用简单的
所谓转义是在解释时特殊字符被赋予了特殊意义,!!的拓展在转义之后,自然就是原生支持,没什么特别的
作者: find    时间: 2012-1-25 11:45

回复 11# aries215


需要拖动的,都是蛋疼的
作者: watermark    时间: 2012-1-25 14:31

回复 19# defanive
你的代码我实在看不懂,请原谅我水平有限。
就事论事的说,不管什么叫“转义”,我那个批处理不需要用到。
作者: defanive    时间: 2012-1-26 10:01

回复 21# watermark
那你发出来吧,看不到你代码我也不好评论
作者: qzwqzw    时间: 2012-1-27 09:55

楼主在新年钟声敲响时发帖
钻研精神实在可嘉!
感觉很像某位大神的作风

至于楼顶提到的命令行参数传递特殊字符的问题
因为我曾经参与过讨论并给出了"批处理基本无解"的推论
自然很有兴趣了解有人可以打破这个推论找到新思路

不过看了楼主的所有发帖
似乎都没有测试 (abc)&(xyz).cmd
那是我在你引用的旧帖中所遗留下的尾巴问题
如果你的代码能通过就非常有意义了

建议你参照引用帖中的代码建立测试文件
这样的测试结果更容易引起原帖的参与者的共鸣
另外建议代码结果尽量不要用贴图
会把一些潜在的讨论者拒之门外
包括很多手机wap用户和所有匿名用户

CrLf版主的两段代码都有新奇之处
尤其第一段代码的创新令人击节
可惜兼容性也要差一些
另外两端代码都不支持多文件同时拖拽

defanive似乎没有注意到11楼aries215老兄的提醒
原帖讨论的是“拖至批处理的图标上执行”
而非“批处理的窗口内执行”
所以使用set/p的方向就是有误的

至于拖动文件到批处理图标上运行
是否如find在20楼所说的“蛋疼”
那就是另外一回事了
此处不论
作者: dnfreeuser    时间: 2012-1-27 20:18

%CMDCMDLINE%
在这里面提取行不?
作者: yue    时间: 2012-1-27 21:48

  1. set "ddrx=%*"
  2. set "vbrx=%ddrx:"=%"
  3. if "%vbrx:~-4%"==".txt" set "vbrx=%vbrx:~0,-4%_txt"
  4. md "%vbrx%"
  5. pause
复制代码
把上面几段代码用"Quick Batch File Compiler“软件包装一下成EXE文件
然后把txt文件拖到这个EXE文件上即可实现
楼主是这样吗?
作者: watermark    时间: 2012-1-30 16:01

回复 25# yue
不是啦, 原生就是不需要借助任何第三方工具, 像平常那样编写和执行批处理.
还有, 我并没有指定后缀, 拖入任意后缀的文件都OK.

回复 23# qzwqzw

等的就是你, 呵呵~

首先, 跟"CrLf"版主说一声 Sorry, 让你受委屈了!

(abc)&(xyz) 这类文件名我开始时就测试通过的, 觉得还不够特殊, 才上1楼的图. 只要是合法的文件名, 都能通过测试.
下面这样的文件(夹)名称包含了几乎全部合法的特殊字符, 够复杂了吧?! 嗯, 抱歉, 我还得再贴两张图, 感觉比较直观. 俗话说, 有图有真相.
作者: CrLf    时间: 2012-1-30 17:00

回复 26# watermark


    贴 100 张图不如贴出代码...
作者: watermark    时间: 2012-1-30 17:10

这么夸张? 我没有意识到哦...

好吧, 先贴开头两行代码:
  1. SetLocal EnableDelayedExpansion
  2. Set tsr=!*
复制代码

作者: yue    时间: 2012-1-30 18:59

回复 26# watermark


    都想不出来了,楼主真是人才了
作者: CrLf    时间: 2012-1-30 19:55

本帖最后由 CrLf 于 2012-1-30 20:28 编辑

汗,还是不懂...
话说参数为“(abc)&(xyz).txt”时,应该会出现语法错误,连 cmd 都打不开的啊,为什么楼主能正常运行...
好奇,静待答案揭晓。
作者: qzwqzw    时间: 2012-1-31 21:20

回复 30# CrLf
我也很好奇楼主怎么绕过这个限制的
我所能想到的方式是
把文件放到名称带空格的目录中
然后再往批处理上拖动
依靠固有的空格给文件完整路径加上引号对
作者: watermark    时间: 2012-2-1 18:27

我的系统是NT6, "文档"的实际路径没有任何空格, 图片没作修改的, 如下:
C:\Users\Administrator\Documents\A&=^,;%()@~$'{}B\

引号是后面echo时添加的.

大家能根据28楼的两行代码想到什么没?
作者: watermark    时间: 2012-2-14 19:22

本帖最后由 watermark 于 2012-2-14 19:27 编辑

忙呀, 差点忘记了!

贴一份能证明标题的代码:
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. set tsr=!*
  4. if defined tsr (
  5. for /f "tokens=*" %%i in ("!tsr!") do  (
  6.     for  %%a in (%%i) do (
  7. cd /d "%~dp0"
  8. set filea=%%~a
  9. set exta=%%~xa
  10. set name=%%~na
  11. set patha=%%~dpa
  12. set folder=!name!_!exta:~1!
  13. set pathb=!patha!!folder!
  14. call :action
  15. pause>nul
  16. )
  17. )
  18. )
  19. :action
  20. echo "%filea%"
  21. echo "%exta%"
  22. echo "%folder%"
  23. md "%folder%"
  24. echo "%cd%"
  25. cd "%pathb%"
  26. echo on
  27. echo "%cd%"
  28. @echo off
  29. goto eof
  30. :eof
复制代码
这份代码不能直接绕过(abc)&(xyz)形式的限制, 但拖入别的文件能枚举同目录下任何含特殊字符的文件.
作者: powerbat    时间: 2012-2-15 00:12

我想看可以绕过(abc)&(xyz)形式的代码
作者: CrLf    时间: 2012-2-15 10:46

回复 33# watermark


    晕倒...
    这效果的实现并不源于 !*,而是 * 在 for 中作为通配符匹配文件,所以生效的实际上是这句:
  1. for  %%a in (%%i) do ...
复制代码
因此直接写成
  1. for  %%a in (*) do md %%~ni
复制代码
的运行结果也是一样的,仅受所拖动文件的目录影响,不受文件影响。

    变量解释和参数扩展是两码事,! 虽然和 % 一样能用来解释变量,但是并不被承认用于扩展参数,这个概念区别要分清。
作者: CrLf    时间: 2012-2-15 10:54

回复 34# powerbat


    理论上应该还有一大把,比如 if=.cmd  for;.bat  &&&.txt,各种非法语法,各种恶心文件名
作者: qzwqzw    时间: 2012-2-17 22:52

回复 33# watermark
老实说
我也为楼主的这种避实击虚的思路雷到了
很想收回在23楼所做的预测
代码就不再分析了
作者: garyng    时间: 2012-2-22 21:36

本帖最后由 garyng 于 2012-2-22 21:40 编辑

还记得 这编帖子么?
[未彻底解决]多个文件拖到cmd窗口后,如何获取每一文件的完整路径
qzwqzw大大(在我楼上呢~)在第7楼写着:

用批处理的办法基本无解

这个问题源于Explorer的拖放扩展程序shell32.dll
注册表路径位于HKEY_CLASSES_ROOT\CLSID\{86C86720-42A0-1069-A2E8-08002B30309D}
因为它没有将“&"视为转义符号
所以不会用引号对将其扩起取消转义

所以对于这个问题无非以下几个方案:
1、修改拖放扩展程序shell32.dll,让它可以处理"&"的情况;
2、新建拖放扩展程序,专门处理cmd之类程序的路径过滤;
3、在处理前告知用户使用"&"的情况可能出错,交由用户处理发生的异常;


楼主说:
把含有任意 =,;&^~@#$%()' 字符的文件拖放至批处理的图标上, 生成一个新的文件夹



在图片看到了“&” 字符

因为它没有将“&"视为转义符号
所以不会用引号对将其扩起取消转义



难道 楼主 写了个第3方? 还是 修改了 shell32.dll?!




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2