当我使用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()
我得到的信息是:
Exception thrown: [Error 6] The handle is invalid
但是,如果我没有指定'stdout'参数,则subprocess.call()启动就可以了。
我可以看到pythonw.exe可能正在重定向输出本身,但我无法理解为什么我被阻止为新线程指定stdout。
答案 0 :(得分:7)
sys.stdin
和sys.stdout
句柄无效,因为pythonw在作为deamon运行时不提供控制台支持,因此subprocess.call()
的默认参数失败。
Deamon程序有目的地关闭stdin / stdout / stderr并使用日志记录,因此您必须自己管理:我建议使用subprocess.PIPE。
如果您真的不关心子流程对错误和所有内容的说法,那么您可以使用os.devnull
(我不确定它有多便携?)但是我不建议这样做。
答案 1 :(得分:6)
为了记录,我的代码现在看起来像这样:
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指定一个管道,然后我们立即关闭它。
答案 2 :(得分:2)
这是一个老问题,但pyInstaller也出现了同样的问题。
事实上,任何在没有控制台的情况下在python for exe中转换代码的框架都会发生这种情况。
在我的测试中,我观察到如果我在我的spec文件(pyInstaller)中使用标志“console = True”,则不再出现错误。
解决方案遵循Piotr Lesnicki的提示。