.pyw和pythonw不在Windows 7下运行

2024-05-29 04:01:32 发布

您现在位置:Python中文网/ 问答频道 /正文

运行简单的.py或.pyw python文件会导致python.exe显示在任务管理器下。

python myApp.py
python myApp.pyw

但是,当我们尝试在不使用控制台的情况下运行它时,脚本似乎不会运行,任务管理器下也不会出现python.exepythonw.exe

pythonw myApp.pyw
pythonw myApp.py

我们如何解决这个问题?系统正在运行Python2.7.8x64。


Tags: 文件py脚本管理器系统情况exemyapp
3条回答

tl;dr

  • 要排除故障,请在调用时使用输出重定向:

    pythonw myApp.py 1>stdout.txt 2>stderr.txt
    

这将捕获来自print()、文件stdout.txt中的stdout输出和来自PowerShell的文件stderr.txt中的stderr输出(例如来自未处理的异常);使用
cmd /c pythonw myApp.py 1>stdout.txt 2>stderr.txt.
注意,重定向stdout的行为实际上可能会使脚本再次工作,如果它失败的唯一原因是使用了pythonw(在Python 2.x中-见下文)。
警告:当直接调用*.pyw脚本时,这种输出重定向技术似乎不起作用(而不是通过将脚本文件路径传递给pythonw.exe)。如果您知道原因和/或它对您有用,请告诉我。

  • 要修复脚本:

将以下内容放在要用pythonw.exe运行的任何Python 2.x或3.x脚本的顶部:

import sys, os
if sys.executable.endswith("pythonw.exe"):
  sys.stdout = open(os.devnull, "w");
  sys.stderr = open(os.path.join(os.getenv("TEMP"), "stderr-"+os.path.basename(sys.argv[0])), "w")

这可确保在使用pythonw.exe运行脚本时执行以下操作:

  • print()sys.stdout()的调用和显式调用被有效地忽略(不是操作)。
  • Stderr输出,包括未处理的致命异常发送到文件 %TEMP%\stderr-<scriptFileName>%TEMP%是一个标准的Windows环境变量,它指向当前用户文件夹中的临时文件。

换言之:使用上述代码,当使用pythonw.exe调用脚本时,在脚本无提示失败后检查文件%TEMP%\stderr-<scriptFileName>

要得到解释,请继续阅读。


在Windows上,pythonw.exe用于在所有脚本上启动GUI/no UI,这意味着 标准输入和输出流-sys.stdinsys.stdoutsys.stderr不可用。

这有两个讨厌的副作用:

  • 使用print()-默认情况下目标是sys.stdout-会导致Python 2.x中出现异常。
    • 这个问题已经在Python3.x中解决了
  • 任何未处理的异常-包括由2.x中的print()触发的异常-导致脚本自动中止
    • 默认情况下,异常错误消息会转到sys.stderr,这在本场景中是不可用的。

上述代码通过以下方法解决了这些问题:

  • 将stdout输出发送到空设备,有效地忽略任何试图输出到sys.stdout的尝试-无论是显式的还是隐式的通过print()

  • 将所有stderr输出发送到临时文件。


Python2.x和Python3.x之间的区别:

当使用pythonw.exesys.stdinsys.stdoutsys.stderr运行脚本时:

  • 在Python中:haveinvalid文件描述符
    • 当试图写入sys.stdoutsys.stderr时,最终的结果是以下异常:IOError: [Errno 9] Bad file descriptor
    • 陷阱:由于输出缓冲,这个异常可能不会出现,直到您输出了4K字节;您可以通过使用-u(对于无缓冲输出)调用pythonw.exe立即触发它。
    • print()盲目尝试sys.stdout(默认情况下),因此迟早会引发此异常。
  • 在Python中:将设置为None
    • 当发现sys.stdoutNone时,3.xprint()函数执行no op(不执行任何操作)作为补充,这样print()语句在默认情况下就可以安全地使用-当与pythonw.exe一起运行时,它们将被忽略
    • 但是,尝试使用sys.stdout.write()sys.stderr.write()仍然会导致异常。

有关更多背景信息,请参见here

我在自己的脚本上遇到了同样的问题,发现当添加Ross的答案的输出时,脚本实际上会运行。

出于某种原因,重定向输出似乎解决了问题。由于我对将输出写入磁盘不感兴趣,所以我改为使用以下命令将其写入/dev/null(或等效于平台的命令):

if ( sys.platform == 'win32' and sys.executable.split( '\\' )[-1] == 'pythonw.exe'):
    sys.stdout = open(os.devnull, 'w')
    sys.stderr = open(os.devnull, 'w')

if语句确保只在脚本从pythonw.exe启动时发生。我不确定它是否相关,但在其他导入(包括import logging)之前执行此操作很重要。

尝试将import sys; sys.stderr = open("errlog.txt", "w")行添加到myApp.py的开头。然后在errlog.txt中查找回溯或任何其他错误消息。

相关问题 更多 >

    热门问题