В 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 для открытия *.ps1
файлов (т. е. команду, связанную с глаголом оболочки Open
), чтобы передать путь к файлу под рукой в CLI PowerShell ( powershell.exe для Windows PowerShell, pwsh для PowerShell (Core) 7) для выполнения.
Примечание. Поведение по умолчанию при открытии файлов *.ps1
извне PowerShell (включая их вызов из cmd.exe
и двойной щелчок в проводнике) — их открытие для редактирования. Изменение поведения выполнения сценариев PowerShell может быть неожиданным для других пользователей, поэтому лучше ограничить это изменение своей учетной записью пользователя.
Ответ SuperUser, на который вы ссылаетесь, показывает, как это сделать через реестр; обратите внимание, что связанный код требует повышения прав, т. е. запуска с правами администратора.
Чтобы subprocess.run()
мог использовать переопределенную команду, необходимо передать shell=True
(который вызывается через cmd.exe
, который автоматически вызывает операцию оболочки Windows по умолчанию для неисполняемых файлов):
import subprocess as sp
# Performs the "Open" Window shell operation on the *.ps1 file.
sp.run(["D:/Temp/hello.ps1"], shell=True)
Если вы не хотите переопределять команду, связанную с глаголом оболочки Open
, ваш единственный вариант — это вызывать файлы *.ps1
через PowerShell CLI; например.:
import subprocess as sp
sp.run(["powershell.exe", "-NoProfile", "-File", "D:/Temp/hello.ps1"])