windows - 在使用PowerShell的控制台中使用CMD脚本时,是否存在根本的不兼容性?

标签 windows powershell batch-file cmd automation

我为自动化套件提供了广泛的CMD脚本集。

在使用CMD.exe的控制台中,一切正常。安装Windows Creator的更新后,PowerShell通过Explorer的菜单选项成为新的默认Windows Shell,我的脚本会随机中断。我不能为repro提供任何有意义的代码,主要有两个原因:

  • 没有明显的错误发生。我的自动化脚本刚刚挂起,最终
  • 每次甚至都没有在同一个地方发生停止

    我可以告诉您的是,该套件很大程度上依赖于退出代码,findstr.exetype的使用。

    我知道Windows宏之类的东西,例如%Var%不兼容,但是我假设由于我唯一的调用是对.bat文件的调用,因此.bat行为将是我唯一需要担心的事情。

    如果不是这种情况,我的初始.bat是否应该使用我的参数来触发CMD.exe实例的直接执行?如果是这样,那么对PowerShell友好的最佳方法是什么?

    最佳答案

    eryksun's对这个问题的评论都值得关注。

    答案的这一部分为问题标题中的一般问题提供了一般答案。请参阅下一部分,以了解针对OP方案的特定注意事项。

    一般来说,从PowerShell调用批处理文件时,只需要注意一些事项:

  • 始终在文件名中包含特定的文件扩展名(.bat.cmd),例如script_name.bat
  • 这样可以确保不会意外执行具有更高优先级的同一命令的其他形式(在示例中名为script_name),该形式可以是:
  • 如果命令名称中没有路径组件:
  • 别名,函数,cmdlet或外部可执行文件/PowerShell脚本(*.ps1),恰好位于$env:PATH(%PATH%)变量中前面列出的目录中;如果多个具有相同名称的可执行文件位于同一(最早)目录中,则下一点也适用。
  • 如果命令名称包含路径组件:
  • 具有相同文件名根的PowerShell脚本(*.ps1)或可执行文件,其扩展名位于.bat环境变量中的.cmd%PATHEXT%之前。
  • 如果批处理文件位于当前目录中,则必须在文件名前加上./
  • 通过设计,作为一种安全措施,PowerShell与cmd.exe不同,它不会仅通过文件名调用位于当前目录中的可执行文件,因此,调用script_name.bat来调用当前目录中具有该名称的批处理文件是不起作用的。[1]
  • 相反,您必须使用路径将此类可执行文件作为目标,以便明确表示打算执行当前目录中某些内容的意图,并且最简单的方法是使用前缀./(.\,如果仅在Windows上运行);例如./script_name.bat
  • 将参数传递到批处理文件时:
  • 要么:请注意PowerShell的解析规则,该规则在将参数传递到批处理文件之前应用-请参阅我的this answer
  • 或:使用--%(PSv3+ stop-parsing symbol)来传递其余参数,就好像它们是从批处理文件传递过来一样(除%<var>%样式的环境变量引用扩展之外,PowerShell不会对其进行解释)。

  • [1] eryksun指出,在Vista +上,您可以通过定义环境变量cmd(它的特定值无关紧要),使NoDefaultCurrentDirectoryInExePath的行为类似于PowerShell。
    尽管不明智,但是您仍然可以通过将.显式添加到%PATH%/$env:PATH变量中来强制两种环境始终在当前目录中找到可执行文件;如果在.之前添加前缀,则会获得默认的cmd行为。

    至于您的特定情况:

    After installing the Windows Creator's update, where PowerShell becomes the new default Windows shell via Explorer's menu options



    这适用于以下情况:
  • 现在,按Win-X(系统级键盘快捷键)将提供PowerShell,而不是弹出的快捷菜单中的cmd。
  • 现在,使用File Explore的File菜单显示Open Windows PowerShell代替Open command prompt(cmd)。

  • 但是,对于从文件资源管理器中打开/双击批处理文件时如何调用批处理文件没有什么改变:注册表中HKEY_CLASSES_ROOT\batchfileHKEY_CLASSES_ROOT\cmdfile的子项仍将shell\open动词定义为"%1" %*,应调用批处理文件像以前一样隐式地使用cmd /c

    但是,根据您的注释,批处理文件永远不会直接从文件资源管理器运行,因为它需要参数值,并且它通过两种基本方式调用:
  • 在按Win-R(系统范围的键盘快捷键)后出现的cmd对话框中输入cmd后,通过Run控制台显式地进行操作。
  • 在这种情况下,所有操作都应像以前一样:从cmd调用批处理文件。
  • 使用文件资源管理器的File菜单通过PowerShell显式进行。
  • 根据您的评论,可以打开PowerShell控制台:
  • 直接在目标批处理文件所在的目录中。
  • 祖先目录中的
  • ,例如批处理文件所在的拇指驱动器的根目录。
  • 在这两种情况下,PowerShell对参数的潜在解释都会发挥作用。
  • 此外,在第二种情况下(祖先目录),仅当批处理文件不依赖于当前目录或显式设置当前目录(例如,使用cd /d "%~dp0"将其设置到其自己的位置)时,调用才会起作用。
  • 关于windows - 在使用PowerShell的控制台中使用CMD脚本时,是否存在根本的不兼容性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44637771/

    相关文章:

    windows - PowerShell v3安装错误

    mysql - 使用 MySQL Workbench 从 Windows 连接到远程 MySQL DB (Linux)。远程数据库连接需要本地套接字

    c# - 批处理脚本在调用 exe 后错误退出

    python - 多次执行 Python 脚本的批处理脚本

    C++ 确定声音是否播放完毕

    PHP 脚本未在命令提示符 Windows 7 中运行

    powershell - 跨多个函数共享参数定义的模式

    powershell - 比较参数无法正常工作

    powershell - 在Jenkins主节点和从节点之间共享文件

    input - 如何将用户的字符串从批处理文件输入到环境变量中