从Python启动一个完全独立的过程

时间:2012-11-27 20:10:20

标签: python windows-installer popen

我正在尝试从python启动一个完全独立的进程。我不能使用像os.startfile这样简单的东西,因为我需要传递参数。目前我正在使用subprocess.popen,它让我获得了90%的目标。

args = ["some_exe.exe", "some_arg", "another_arg"]
subprocess.Popen(args, creationflags=DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)

使用带有分离创建标志的popen& std *的管道确实启动了一个新进程,它在父进程终止后继续存在。这一切都很好。问题是新的'子'进程仍然保留了父进程的幻象句柄。因此,如果我尝试卸载父exe(我的python脚本通过pyinstaller捆绑到exe中),msiexec会抱怨父exe仍然在使用。

所以我们的目标是生成一个完全独立的进程来运行“some_exe.exe”,它没有任何句柄回原始进程。

注意:这适用于Windows XP及更高版本。我正在开发Win7。

2 个答案:

答案 0 :(得分:23)

我想我找到了答案。通过Popenclose_fds = True一起使用,我能够启动一个独立且没有父句柄的进程。

对于文档,请查看here并搜索close_fds

  

或者,在Windows上,如果close_fds为true,则不会继承任何句柄   通过子进程。请注意,在Windows上,您无法设置close_fds   为true并通过设置stdin重定向标准句柄,   stdout或stderr。

请注意,此解决方案仅适用于Windows。我不知道任何* nix系统。

答案 1 :(得分:4)

我发现了here

在Windows(win xp)上,父进程在longtask.py完成其工作之前不会完成。这不是你想要的CGI脚本。问题不是Python特有的,在PHP社区中问题是一样的。

解决方案是将DETACHED_PROCESS Process Creation Flag传递给win API中的基础CreateProcess函数。如果你碰巧安装了pywin32,你可以从win32process模块​​导入标志,否则你应该自己定义:

DETACHED_PROCESS = 0x00000008

pid = subprocess.Popen([sys.executable,“longtask.py”],                        creationflags = DETACHED_PROCESS).pid