简体   繁体   English

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

[英]Python subprocess.call() fails when using pythonw.exe

I have some Python code that works correctly when I use python.exe to run it, but fails if I use pythonw.exe. 当我使用python.exe运行它时,我有一些Python代码可以正常工作,但如果我使用pythonw.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()

The message I get is: 我收到的消息是:

Exception thrown: [Error 6] The handle is invalid

However, if I don't specify the 'stdout' parameter, subprocess.call() starts okay. 但是,如果我没有指定'stdout'参数,则subprocess.call()启动正常。

I can see that pythonw.exe might be redirecting output itself, but I can't see why I'm blocked from specifying stdout for a new thread. 我可以看到pythonw.exe可能正在重定向输出本身,但我不明白为什么我被阻止为新线程指定stdout。

sys.stdin and sys.stdout handles are invalid because pythonw does not provide console support as it runs as a deamon, so default arguments of subprocess.call() are failing. sys.stdinsys.stdout句柄无效,因为pythonw在作为deamon运行时不提供控制台支持,因此subprocess.call()默认参数失败。

Deamon programs close stdin/stdout/stderr purposedly and use logging instead, so that you have to manage this yourself: I would suggest to use subprocess.PIPE. Deamon程序有目的地关闭stdin / stdout / stderr并使用日志记录,因此您必须自己管理:我建议使用subprocess.PIPE。

If you really don't care about what the sub process says for errors and all, you could use os.devnull (I'm not really sure how portable it is?) but I wouldn't recommend that. 如果你真的不关心子进程对错误和所有的os.devnull ,你可以使用os.devnull (我不确定它有多可移植性?)但我不建议这样做。

For the record, my code now looks like this: 为了记录,我的代码现在看起来像这样:

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

Note that, due to an apparent bug in the subprocess module, the call to Popen() has to specify a pipe for stdin as well, which we close immediately afterwards. 请注意,由于子进程模块中存在明显的错误,对Popen()的调用也必须为stdin指定一个管道,然后我们立即关闭它。

This is an old question, but the same problem happened with pyInstaller too. 这是一个老问题,但pyInstaller也发生了同样的问题。

In the truth, this will happen with any framework that converts code in python for exe without console. 事实上,任何框架都可以在没有控制台的情况下在python for exe中转换代码。

In my tests, I observed that if I use the flag "console=True" into my spec file (pyInstaller) the error no longer occurs. 在我的测试中,我观察到如果我在我的spec文件(pyInstaller)中使用标志“console = True”,则不再出现错误。 .

The solution was follow the tip of Piotr Lesnicki. 解决方案遵循Piotr Lesnicki的提示。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM