我正在使用一种在Powershell子进程中处理视频处理的软件。
使用 PyCharm,当我运行我的软件(在调试模式下(时,一切都按预期工作。
当我使用 pyinstaller 和 inno 安装程序制作可执行文件并将其安装在 Windows 上时,我在子进程启动时收到此错误:
[WinError 6] The handle is invalid
我想这是由于像这段代码这样的子进程中的错误:
try:
psa1_path = EnvValues.powershell_path().format(project=project)
# using this powershell : C:/Users/${USERNAME}projectsdemocmdpowershell.ps1 -m -v 'CC 2018' -wait windowstyle hidden
dc_logger.info(f'using this powershell : {psa1_path}')
if project:
dc_logger.info("PowerShell Rendering Started")
with open(EnvValues.frame_path(), 'a') as f:
p = subprocess.Popen(['C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe',
'-ExecutionPolicy',
'Unrestricted',
psa1_path],
stdout=f)
p.communicate()
dc_logger.info("PowerShell Done Rendering")
return True
else:
dc_logger.info("no project to render")
return False
该错误是否与传递给子进程的参数有关?为什么代码的可执行版本是唯一不起作用的版本?为什么我在开发版本中没有错误?
这是我的pyinstaller cmds :
pyinstaller --onefile -w -F -i "C:Usersmy_projecticon.ico" Project.py
pyinstaller --onefile -w -F -i "C:Usersmy_projecticon.ico" Project.spec
然后我把它放在InnoSetup中,并将输出安装到我的Windows机器上。
问题出在变量psa1_path
C:/Users/${USERNAME}projectsdemocmdpowershell.ps1 -m -v 'CC 2018' -wait windowstyle hidden
此变量具有参数。subprocess.Popen
将其用作字符串,然后您必须设置shell=True
以便 Popen 将此字符串用作完整的 shell cmd。
p = subprocess.Popen(['C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe',
'-ExecutionPolicy',
'Unrestricted',
psa1_path],
stdout=f, shell=True, stdin=subprocess.DEVNULL)
不要忘记添加 stdin arg,因为它也会抛出[WinError 6] The handle is invalid
那么为什么代码适用于调试代码而不是可执行文件:
这主要是因为 PyCharm 在运行程序时会在幕后进行额外的配置和设置。
因为当你从 IDE 转到运行时时,你需要额外的钩子来让事情顺利进行。 pyinstaller 对 shell 部分的子处理方式与 pyCharm
不同