代码之家  ›  专栏  ›  技术社区  ›  Charles Anderson

使用pythonw.exe时Python subprocess.call()失败

  •  5
  • Charles Anderson  · 技术社区  · 17 年前

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

        def runStuff(commandLine):
            outputFileName = 'somefile.txt'
            outputFile = open(outputFileName, "w")
    
            try:
                result = subprocess.call(commandLine, shell=True, stdout=outputFile)
            except:
                print 'Exception thrown:', str(sys.exc_info()[1])
    
        myThread = threading.Thread(None, target=runStuff, commandLine=['whatever...'])
        myThread.start()
    

    我收到的信息是:

        Exception thrown: [Error 6] The handle is invalid
    

    但是,如果我没有指定“stdout”参数,subprocess.call()将正常启动。

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

    3 回复  |  直到 17 年前
        1
  •  7
  •   Piotr Lesnicki    17 年前

    sys.stdin 和 sys.stdout 句柄无效,因为pythonw在作为deamon运行时不提供控制台支持,因此默认参数为 subprocess.call() 失败了。

    Deamon程序有目的地关闭stdin/stdout/stderr并使用日志记录,因此您必须自己管理:我建议使用子进程。管道。

    如果你 真正地 不在乎子流程对错误的解释,你可以使用 os.devnull (我真的不确定它有多便携?)但我不建议这样做。

        2
  •  7
  •   Charles Anderson    17 年前

    为了记录在案,我的代码现在看起来像这样:

    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())
    

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

        3
  •  2
  •   Eduardo    12 年前

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

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

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

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