【问题标题】:What are these lines of batch code for?这些批处理代码行是做什么用的?
【发布时间】:2016-10-18 22:29:43
【问题描述】:

我在 SuperUser 上遇到了以下批处理代码,其目的是以编程方式替换文件夹的图标。

CD "%userprofile%\desktop"
MKDIR "TEST FOLDER"
ATTRIB +s "TEST FOLDER"
CD "TEST FOLDER"
COPY /Y "%userprofile%\desktop\image.ico" "./image.ico"
ECHO [.ShellClassInfo] >> desktop.txt
ECHO ConfirmFileOp=0 >> desktop.txt
ECHO NoSharing=1 >> desktop.txt
ECHO IconFile=image.ico >> desktop.txt
ECHO IconIndex=0 >> desktop.txt
ECHO InfoTip= >> desktop.txt
CHCP 1252 >NUL
CMD.EXE /D /A /C (SET/P=ÿþ)<NUL > desktop.ini 2>NUL
CMD.EXE /D /U /C TYPE desktop.txt >> desktop.ini
DEL /F /Q desktop.txt
ATTRIB +S +H desktop.ini image.ico

我很容易得到脚本的其余部分,但我无法理解这三行:

CHCP 1252 >NUL
CMD.EXE /D /A /C (SET/P=ÿþ)<NUL > desktop.ini 2>NUL
CMD.EXE /D /U /C TYPE desktop.txt >> desktop.ini

SS64 告诉我 chcp 1252 与称为 "code page" 的东西有关,1252 对应于“西欧拉丁语”,所以我最好的猜测是这会强制脚本使用拉丁字符集。后两行打开 CMD 的实例; SS64 表示第一个上的 /A 开关使其以 ANSI 输出,而第二个上的 /U 使其输出 Unicode。这大约是我所能推测的,如果有人能仔细阅读这三行的每个主要部分并告诉我他们在做什么,我将非常感激。

谢谢!

【问题讨论】:

  • chcp 更改键盘的代码页:read more 和 cmd 行操作您的 desktop.ini
  • @mtizziani:代码页和键盘完全不相关。 CHCP 将数据的解释从 STDIN 更改为控制台的 STDOUT。

标签: windows shell batch-file command-line cmd


【解决方案1】:

简而言之,代码[1]

  • 创建一个临时desktop.txt文件,其内容最终将变为desktop.ini,但使用不同的编码

  • 然后,相关命令将当前控制台代码页编码文件 desktop.txt(例如,在 en-US 系统上,CP-437)转换为 UTF-16 LE 编码文件 desktop.ini,这是文件资源管理器用来控制手头文件夹显示的(与文化无关的)文件。

  • desktop.ini 文件和关联的图标文件image.ico 设置system (+S) 和hidden (+H) 属性,因为这些文件应该是这样的标记(假设它们仅控制包含文件夹的显示,而不是数据文件本身)。

具体来说,感兴趣的 3 行执行以下操作:

  • CHCP 1252 &gt;NUL(静默)更改为 Windows-1252 代码页。

  • CMD.EXE /D /A /C (SET/P=ÿþ)&lt;NUL &gt; desktop.ini 2&gt;NUL 有效地将字符串ÿþ 发送到输出文件desktop.ini - ÿþ,当解释为Windows-1252 编码字符串时,相当于字节0xFF 0xFE,即BOM(字节顺序标记) 用于识别UTF-16 LE编码的文件;换句话说:将此字符串发送到文件desktop.ini 将其标记为UTF-16 LE 编码文件。

    • /D 只是禁止任何可能通过注册表定义的自动运行功能
    • /A 告诉 cmd.exe 输出“ANSI”编码的字符串,其中“ANSI”指的是默认代码页 - 现在设置为 Windows-1252
    • /C 表示以下参数应作为命令执行,cmd.exe 应在命令终止后退出。
  • CMD.EXE /D /U /C TYPE desktop.txt &gt;&gt; desktop.ini 然后追加之前创建的desktop.txt 文件的内容到desktop.ini,使用“Unicode”(UTF-16 LE)编码(感谢/U) ,这样就完成了临时文件desktop.txtUTF-16 LE-encoded desktop.ini的转换(之后desktop.txt被删除)。


[1]
这个答案解释了代码的intent,这并不意味着它一定工作,尤其是在 Windows 10 中;例如,以交互方式分配图标似乎设置了一个不同的 single 属性,该属性组合图像文件及其特定内部资源的索引:例如,IconResource=C:\Users\jdoe\Desktop\image.ico,0

至于需要创建UTF-16 LE-encoded 文件:这不是一个严格的要求 - 显然,Windows 本身,当您使用文件资源管理器分配图标时,会在当前 legacy 中创建文件- 单字节 - 编码(例如,Windows-1252)。
也就是说,使用 文化无关 编码,例如 UTF-16 LE,至少在原则上是最稳健的方法。
但是,如果您写入 desktop.ini 的所有值都是纯 ASCII 字符(7 位范围),则可以安全地将 echo 输出直接通过管道传输到 desktop.ini

归根结底,使用批处理文件来确定文件夹显示属性是一种脆弱的方法,因为它本质上是基于官方的逆向工程API - 可能会改变。

更一般地说,现在最好避免使用批处理文件来执行任何事情 - 改用 PowerShell。

【讨论】:

  • 感谢您提供详细信息。首先创建一个临时文本文件,然后将其转换为UTF-16 编码是否有任何目的?看起来真的很纠结。任何一个都可以简化吗? .ini 是否需要在 UTF-16 中编码 - 您可以不直接创建文件而只需添加 systemhidden 属性吗?
  • @Hashim:请查看我的更新。恐怕我要放弃在这个兔子洞里走得更远了……
  • 哈哈,这已经足够公平了,这是一个非常彻底的答案。我还有更多问题,在得到回答后可能还有更多问题 - 这似乎是每个答案都会为我带来 2 个以上问题的领域之一,可能由于缺乏大局的基础而无济于事,这也太远了容易迷失在问题的兔子洞中。非常感谢。
  • @Hashim:谢谢;很高兴你发现它有用。 Windows 命令处理器 (cmd.exe) 的批处理语言一直受到严重限制,并且多年来几乎没有发展。过去,人们巧妙地将其扩展到极限以完成任务,但随着 PowerShell 的出现,不再有理由挣扎。 PowerShell 不仅是一个强大的 shell,而且在 shell 中独一无二,它能够通过 .NET 框架进行系统调用,这意味着您在 PowerShell 中不能做的事情很少(尽管性能可能是一个问题)。
  • PowerShell 是否允许您像批处理脚本一样创建可执行的 .bat 文件或等效文件?
猜你喜欢
  • 2015-12-23
  • 1970-01-01
  • 2021-12-10
  • 2015-01-14
  • 1970-01-01
  • 1970-01-01
  • 2021-05-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多