5

当我使用 python.exe 运行它时,我有一些 Python 代码可以正常工作,但如果我使用 pythonw.exe 会失败。

    def runStuff(命令行):
        outputFileName = 'somefile.txt'
        输出文件 = 打开(输出文件名,“w”)

        尝试:
            结果 = subprocess.call(commandLine, shell=True, stdout=outputFile)
        除了:
            print '抛出异常:', str(sys.exc_info()[1])

    myThread = threading.Thread(None, target=runStuff, commandLine=['whatever...'])
    myThread.start()

我得到的信息是:

    抛出异常:[错误 6] 句柄无效

但是,如果我不指定 'stdout' 参数, subprocess.call() 可以正常启动。

我可以看到 pythonw.exe 可能正在重定向输出本身,但我不明白为什么我被阻止为新线程指定标准输出。

4

3 回答 3

7

sys.stdinsys.stdout句柄是无效的,因为 pythonw 在作为守护进程运行时不提供控制台支持,因此默认参数subprocess.call()失败。

守护程序故意关闭 stdin/stdout/stderr 并改用日志记录,因此您必须自己管理:我建议使用 subprocess.PIPE。

如果您真的不关心子流程对错误和所有内容的说明,您可以使用os.devnull(我不确定它的便携性如何?)但我不建议这样做。

于 2008-12-03T17:26:53.463 回答
7

作为记录,我的代码现在如下所示:

def runStuff(commandLine):
    outputFileName = 'somefile.txt'
    outputFile = open(outputFileName, "w")

    if guiMode:
        result = subprocess.call(commandLine, shell=True, stdout=outputFile, stderr=subprocess.STDOUT)
    else:
        proc = subprocess.Popen(commandLine, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)
        proc.stdin.close()
        proc.wait()
        result = proc.returncode
        outputFile.write(proc.stdout.read())

请注意,由于 subprocess 模块中的一个明显错误,对 Popen() 的调用也必须为 stdin 指定一个管道,然后我们立即关闭它。

于 2008-12-22T14:19:21.973 回答
2

这是一个老问题,但 pyInstaller 也发生了同样的问题。

事实上,任何在没有控制台的情况下将 python 中的代码转换为 exe 的框架都会发生这种情况。

在我的测试中,我观察到如果我在我的规范文件 (pyInstaller) 中使用标志“console=True”,则不再发生错误。.

解决方案是遵循 Piotr Lesnicki 的建议。

于 2014-08-22T18:09:19.477 回答