如何在 Windows 上用 Python 创建挂起的子进程?

问题描述 投票:0回答:2

我想通过

subprocess.Popen
创建一个以挂起状态启动的子进程,以便我可以让它准备好在以后运行。

我在here找到了适用于Linux的解决方案,但找不到适用于Windows的任何解决方案。有谁知道 Windows 上是否有与此等效的程序?

python windows subprocess
2个回答
0
投票

经过更多调查后,我设法创建了一个暂停的进程并稍后恢复它。幸运的是,使用 Popen 和 Windows 创建挂起进程非常简单。

首先,您需要通过运行安装 pywin32:

pip install pywin32

安装 pywin32 后,您可以使用

subprocess.Popen
创建一个挂起的进程:

from win32process import CREATE_SUSPENDED
from subprocess import Popen

pipe = subprocess.Popen(<command>, <**kwargs>, creationflags=CREATE_SUSPENDED)

然而,恢复这个挂起的进程要困难得多,因为它需要一个 PyHandle 来处理挂起的线程。不幸的是,Popen 不会返回为挂起线程打开 PyHandle 所需的线程 ID。作为一种解决方法,我最终对 Popen 的 _execute_child 函数进行了猴子修补,以存储 _winapi.CreateProcess 返回的线程 ID。现在我们有了挂起进程的线程 ID,我们可以恢复线程了。

要恢复挂起的进程,假设您对 Popen 进行了猴子修补以存储线程 ID,请使用:

from win32api import OpenThread, CloseHandle
from win32con import THREAD_SUSPEND_RESUME
from win32process import ResumeThread

thread_handle = OpenThread(THREAD_SUSPEND_RESUME, <inherit handle (T/F)>, pipe.tid)
ResumeThread(thread_handle)
CloseHandle(thread_handle)

如果有人知道一种无需 Monkeypatching _execute_child 即可从 Popen 获取线程 ID 的方法,或者任何更好的挂起和恢复进程的方法,请分享!

资源:

我还为 subprocess.Popen 创建了一个 包装器,如果有人想查看我的具体实现,它会在父进程死亡时杀死子进程。


0
投票

也许我误解了你问题的一些细节,但我可以轻松做到这一点,甚至无需考虑线程和句柄

例如在暂停状态下启动游戏并注入 dll

import subprocess, psutil
from pyinjector import inject

proc = subprocess.Popen(args="-d3d11",executable="Client-Win64-Shipping.exe",cwd=os.getcwd(),shell=False,creationflags=4)
inject(proc.pid, "dxgi.dll")
psutil.Process(proc.pid).resume()

这正是它应该做的,尽管在我尝试使用反作弊的情况下杀死了该过程。此示例中的重要部分是creationflags=4。我还发现了一堆相互矛盾的答案和奇怪的迂回解决方案,建议您通过在管道中发送单字节消息来恢复进程。也许在某一时刻这是必要的,但在 2024 年

psutil.Process(proc.pid).resume()
就是你所需要的

© www.soinside.com 2019 - 2024. All rights reserved.