将 .ps1 转换为 .bat 不会导致 cmd.exe 达到最大字符长度 - 但为什么呢?

2023-12-11

基于一个相关问题和一些谷歌搜索/测试,很明显命令行的最大长度cmd.exe is 8,191人物。然而......我的脚本似乎成功地超过了这个长度,我不明白它为什么有效。

所以我有:

  • 编写/保存为的脚本.ps1
  • I'm 转换它到一个.bat使用来自的方法将 PowerShell 转换为批处理
  • 如果我运行.bat- 似乎没有任何问题
  • 如果我尝试回应$encoded命令或只是删除@echo off在运行之前.bat- 很容易看出的长度/内容$encoded已被截断...但它按预期工作

我意识到这是一个有点奇怪的问题,因为我试图确定一些关于有效的东西与损坏的东西的隐藏真相,但我想了解why这是工作!

Note:我创建的主要原因.bat我的脚本是因为我有许多小“程序”,我需要在我的工作计算机上运行并与其他人共享。我们公司的执行政策不允许运行脚本,如果它是一个脚本,其他人使用我写的东西会容易得多.bat因为他们不需要理解/使用PowerShell。他们只需将.bat在正确的位置,点击两下,然后坐下来放松,直到有事情发生。

EDIT: Here's the truncated command in the cmd.exe window. If I convert from Base64 back to readable text, it is clearly missing about half of the script. Yet - I'm not noticing any problems Truncated Command


  • The 8191- 字符限制适用于交互式命令行并致电cmd.exe's CLI (via cmd /c)

  • It does not apply to commands invoked from batch files - there the limit is close to[1] 32KiB (32,768) characters.

    • 然而,它似乎仍然有选择地适用于cmd.exe's internal命令,例如echo;相比之下,调用外部程序例如powershell.exe不受影响(尽管特定外部程序可能有自己的下限)。

作为旁白:

聪明如的链接方法将 PowerShell 脚本转换为批处理文件 is, 生成的批处理文件缺乏论据支持传递到 PowerShell 代码,并且添加对此的支持是不切实际的(它也需要对参数进行 Base64 编码,在调用时,除非借助非内置实用程序,否则从批处理文件中不可能实现这一点)。

  • 如果您的脚本/批处理文件被写入不需要调用参数或以交互方式提示它们(如您的情况),则无需担心此限制。

  • 然而,您可能出于以下任何原因需要论证支持:

    • 允许调用批处理文件cmd.exe(命令提示符)有参数.
    • To allow calling with arguments from other environments that support passing arguments, notably Task Scheduler and the Windows Run dialog (WinKey-R).
    • 使批处理文件支持拖放(隐式传递拖放文件的路径作为参数)。

至于将 PowerShell 代码包装在批处理文件中的总体原因:

  • 批处理文件(.cmd, .bat)可以启动directly,就好像它们是可执行文件一样,全系统.
  • 相比之下,这是not支持 PowerShell 脚本(.ps1),必须通过显式调用 PowerShell CLI 从外部 PowerShell 调用;请注意,系统可以配置为明确阻止执行.ps1脚本 - 请参阅下一节。

If you do批处理文件中需要参数支持,最好但不方便的解决方案是分发two files:

  • 原本的*.ps1 file...
  • and a 配套批处理文件,与相同的基本文件名,要放置在同一目录- 可以从以下位置调用outsidePowerShell - 其唯一目的是调用*.ps1文件通过powershell.exe带有传递参数。

E.g. foo.cmd会陪伴foo.ps1,具有以下不变的内容:

@powershell.exe -NoProfile -File "%~dpn0.ps1" %*

Note:

  • 重要的:以上假设PowerShell有效执行政策允许执行脚本文件(.ps1).

    • 如果你不能做出这个假设,请将-ExecutionPolicy RemoteSigned before -NoProfile上面(或者,要停用所有检查,-ExecutionPolicy Bypass),但请注意,执行策略基于GPO(组策略对象)仍可能阻止脚本执行。
  • To call PowerShell(核心)7+相反,使用pwsh.exe代替powershell.exe.

  • %~dpn0扩展为封闭批处理文件本身的完整路径没有文件扩展名;追加.ps1因此,将配套的 PowerShell 脚本定位在同一目录中;跑步cmd /c call /?语法的解释。

  • %*传递批处理文件接收到的所有参数。


[1] In practice, the limits appear to be: 32,767 characters in batch files, and - lower by 3 chars. - 32,764 for Powershell (both on the command line / via the CLI and in *.ps1 scripts). In PowerShell, the limit may in practice be even lower than that, because PowerShell expands the names of executables it locates via $env:PATH to their full paths in the command lines constructed behind the scenes, which cmd.exe doesn't do.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 .ps1 转换为 .bat 不会导致 cmd.exe 达到最大字符长度 - 但为什么呢? 的相关文章

随机推荐