在Python中,我们可以使用
subprocess
来原生运行bat
(cmd
)脚本,比如
import subprocess as sp
sp.run(["D:/Temp/hello.bat"])
工作正常。但是,它无法原生运行
ps1
脚本,如之类的代码
import subprocess as sp
sp.run(["D:/Temp/hello.ps1"])
将导致引发“WinError 193:%1不是有效的Win32应用程序”。
我以为是因为
.PS1
没有出现在PATHEXT
中,所以添加到那里,但又失败了。我还尝试了这个答案中提供的方法,它似乎正在设置文件执行策略,但它仍然不起作用。
我知道当我在调用中添加执行器(如
sp.run(["pwsh", "D:/Temp/hello.ps1"])
)或使用 bat
脚本作为中间时,它会起作用,但这不是我们想要的。我正在使用一个从 *nix 移植到 Windows 的程序,它只是调用我作为单个可执行文件提供的任何内容(在 *nix 上我们可以使用 shebang,但不能在 Windows 上使用)。
批处理文件是特殊,因为它们是直接识别为可执行文件的唯一类型的基于解释器的脚本文件。
对于 PowerShell 脚本文件 (
*.ps1
),直接调用时实现其执行的唯一方法是:
将 Windows shell 使用的命令重新定义为 open *.ps1
files(即与
Open
shell 动词关联的命令),以便将手头的文件路径传递到 PowerShell CLI (
powershell.exe
用于 Windows PowerShell,pwsh
用于 PowerShell (Core) 7)用于执行。
注意:从外部 PowerShell 打开 *.ps1
文件(包括从 cmd.exe
调用它们并在文件资源管理器中双击)时,默认
行为是打开它们进行编辑。 将行为更改为执行 PowerShell 脚本可能会被其他用户意外,因此最好将此更改限制为您自己的用户帐户..
显示了如何通过注册表进行操作;请注意,链接的代码需要elevation,即以管理权限运行。
但是,鉴于上述情况,您可能更愿意仅为当前用户定义命令subprocess.run()
使用重新定义的命令,必须传递
shell=True
(通过cmd.exe
调用,它会自动调用对不可执行文件的默认Windows shell操作):
import subprocess as sp
# Performs the "Open" Window shell operation on the *.ps1 file.
sp.run(["D:/Temp/hello.ps1"], shell=True)