[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
用批处理的办法基本无解

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

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

评分人数

    • namejm: 一针见血的分析,很有深度,佩服。技术 + 1
    • FOR: 赞!技术 + 1
    • vsbat: 高手 佩服-技术 + 1
    • yangfengoo: haoPB + 5 技术 + 1

TOP

本帖最后由 qzwqzw 于 2011-4-29 16:30 编辑
说下,和shell32.dll没关系,明显是cmd的事情。。。
slore 发表于 2011-3-25 17:32

呵呵
这可真是公说公有理婆说婆有理了
cmd怪shell32不把&用引号包裹住再交过来
shell32怪cmd自己不把赤裸的&管教好
一嘴烂账没法说清

不过又回头多想了一下
这个问题仍有探索的余地
余地就在%cmdcmdline%
那里包裹了更多的信息
想办法处理了一下
因为以前很少关注转义字符的处理
费了许多功夫才大致完成
最终的结果是给定的12个特殊文件处理了11个
唯一剩下的一个(abc)&(xyz).cmd
没什么好办法
因为它直接导致批处理无法启动
  1. :: 测试多个怪僻文件名直接拖拽到批处理文件上,批处理是否正确处理这些文件名
  2. @echo off
  3. rem pause
  4. if not [%1]==[] goto :start
  5. echo 正在生成测试文件
  6. echo.>abc.cmd
  7. echo.>"abc xyz.cmd"
  8. echo.>"abc^xyz.cmd"
  9. echo.>"abc&xyz.cmd"
  10. echo.>"abc & xyz.cmd"
  11. echo.>"(abc)(xyz).cmd"
  12. echo.>"(abc) (xyz).cmd"
  13. rem echo.>"(abc)&(xyz).cmd"
  14. echo.>"(abc) & (xyz).cmd"
  15. echo.>"abc;xyz.cmd"
  16. echo.>"abc,xyz.cmd"
  17. echo.>"abc=xyz.cmd"
  18. echo @echo 溢出漏洞存在!^&pause>xyz.cmd
  19. echo 测试文件生成.
  20. goto :eof
  21. :start
  22. echo starting...
  23. set _line="%cmdcmdline:"="%"
  24. set _line=%_line:^=^%
  25. set _line=%_line:&=&%
  26. set _line=%_line:(=(%
  27. set _line=%_line:)=)%
  28. set _line=%_line:,=,%
  29. set _line=%_line:;=;%
  30. set _line=%_line: =□%
  31. rem set _line
  32. rem pause
  33. setlocal EnableDelayedExpansion
  34. for %%f in (%_line:~1,-1%) do set _line2=!_line2!=%%f
  35. endlocal & set _line=%_line2:□= %
  36. set _line=%_line:"="%
  37. set _line=%_line:~9,-1%
  38. rem set _line
  39. rem pause
  40. setlocal EnableDelayedExpansion
  41. for %%f in (%_line%) do (
  42. set _file="%%~f"
  43. set _file=!_file:^=^^!
  44. set _file=!_file:&=^&!
  45. set _file=!_file:(=^(!
  46. set _file=!_file:)=^)!
  47. set _file=!_file:,=,!
  48. set _file=!_file:;=;!
  49. set _file=!_file:===!
  50. if exist !_file! (echo ---!_file!---) else (echo ___"%%~f"____)
  51. )
  52. endlocal
  53. echo 结束
  54. pause
复制代码
另外
转义字符的处理过程中
又遇到了等号的替换问题
顺便提供了一种新思路
  1. @echo off & setlocal EnableDelayedExpansion
  2. set _exp=var=value
  3. set _exp
  4. set _exp=%_exp:===%
  5. set _exp
  6. echo 全角等号可以直接替换
  7. pause
  8. set _exp=var=value
  9. set _exp
  10. for %%f in ("=") do (
  11. call set _exp=!_exp:%%~f=-!
  12. )
  13. set _exp
  14. echo 半角等号不能直接替换
  15. pause
  16. set _exp=var=value
  17. set _exp
  18. set _exp=%_exp: =□%
  19. set _exp=%_exp:;=;%
  20. for %%e in (%_exp%) do set _exp2=!_exp2!=%%e
  21. set _exp=%_exp2:□= %
  22. set _exp=%_exp:;=;%
  23. set _exp=%_exp:~1%
  24. set _exp
  25. echo 转折的办法:把非等号的for分隔符替换掉,再用for遍历被等号分隔的所有串,并且用等号的替换字符连接这些串,最后将其它分隔符恢复,不支持处理连续的等号
  26. pause
复制代码
天的白色影子

TOP

qzw居然把我那个例子拿出来了
zqz0012005 发表于 2011-4-29 19:39

恕我无知
竟然不知道那段文字引用了你哪个例子

关于等号替换
我认为稳妥的办法还是逐个字符检测
特殊字符可以另行处理
  1. @echo off
  2. set _exp=if "%%a%%"=="%%b%%" echo 2^^3=8^>out.txt
  3. set _exp
  4. set "_exp=%_exp:"="%"
  5. :loop
  6. if "%_exp:~0,1%"=="=" (
  7. set "_exp2=%_exp2%="
  8. ) else (
  9. set "_exp2=%_exp2%%_exp:~0,1%"
  10. )
  11. set "_exp=%_exp:~1%"
  12. if not "%_exp%"=="" goto :loop
  13. set "_exp=%_exp2:"="%"
  14. set _exp2=
  15. set _exp
  16. echo 老实的办法:逐个字符判断是否等号,是则替换,不是则直接连接
  17. pause
复制代码
天的白色影子

TOP

返回列表