【发布时间】:2017-07-14 13:26:57
【问题描述】:
我想生成一个子进程,如果一切都发生在后台而不打开新的 Windows 控制台,那就太好了。
首先我认为我的代码有问题,因为它在向子进程发送输入时会导致错误。 像 String 这样的命令,例如产生错误
未知动作:tring
意思是,通过stdin.write发送到子进程的输入的第一个字符有时会丢失。
那是代码:
self.sp = subprocess.Popen(
args,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
现在我尝试了以下方法,一切正常。问题是新打开的控制台。
self.sp = subprocess.Popen(
args,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
creationflags = subprocess.CREATE_NEW_CONSOLE
)
是否有其他方法可以在不打开新的 Windows 控制台的情况下实现此目的?
您的链接将我带到 CREATE_NEW_WINDOW 标志的描述
进程也可以通过指定 调用 CreateProcess 中的 CREATE_NEW_CONSOLE 标志。这种方法 创建一个子进程可以访问但不能访问的新控制台 到父进程。单独的控制台支持父母和孩子 与用户交互而不会发生冲突的过程。 如果这个标志是 创建控制台进程时未指定,两个进程都是 连接到同一个控制台,并且不能保证 正确的流程将收到为其准备的输入。 应用程序 可以通过创建不继承的子进程来防止混淆 输入缓冲区的句柄,或仅启用一个子进程 继承输入缓冲区句柄同时防止父级的时间 从读取控制台输入到孩子完成的过程。
如果一个人可以在不打开窗口的情况下创建一个新控制台。
这似乎解决了问题
bufsize=1
谢谢。
【问题讨论】:
-
你可以试试这个方法stackoverflow.com/a/7006424/6120211
-
不管怎样,试试creation flag
CREATE_NO_WINDOW,它会隐式创建一个没有窗口的新控制台(conhost.exe 的实例)。 -
这当然是应该包含在问题中的相关信息,但它并不能解释症状。假设问题是由子程序中的错误引起的,一种可能的解决方法是显式创建一个控制台(在父项中),然后使用 AllocConsole()、GetConsoleWindow() 和 ShowWindow() 隐藏它 - 您可以调用大多数 Win32 Python 中的 API 函数,因此您应该能够做到这一点 - 但这并不理想,因为控制台仍会短暂闪烁。
-
@HarryJohnston,任务管理器将没有窗口的进程显示为“后台”进程。当通过另一个控制台应用程序(例如 cmd.exe)运行时,这适用于 python.exe。控制台窗口由 conhost.exe 托管,但它将有效所有者的进程和线程 ID 存储为窗口数据(索引 0 和 4),例如,
GetWindowThreadProcessId使用这些数据。当前所有者退出时,控制台将其列表中的下一个附加进程提升为所有者,直到没有留下任何进程并且控制台退出。 -
@eryksun,好点子。我没有注意到 Windows 10 中发生了变化。toas939,你能澄清一下你是如何启动父进程的吗?
标签: python windows subprocess windows-console