如何在 Win32 中创建子进程,以便它们在任务管理器中显示为嵌套?

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

我有一个 Win32 C++ 应用程序。我正在尝试使用

CreateProcess
启动一个或多个子进程。我希望当父母关闭时,孩子也关闭。

我通过创建工作并启用

JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
实现了这一目标:

HANDLE hJob = CreateJobObject(NULL, NULL);

JOBOBJECT_EXTENDED_LIMIT_INFORMATION extendedInfo;
ZeroMemory(&extendedInfo, sizeof(extendedInfo));
extendedInfo.BasicLimitInformation.LimitFlags =
    JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;

SetInformationJobObject(
        hJob, JOBOBJECTINFOCLASS::JobObjectExtendedLimitInformation,
        &extendedInfo, sizeof(extendedInfo));

然后将当前(父)和创建(子)进程添加到此作业中:

// assign parent to job
AssignProcessToJobObject(hJob, GetCurrentProcess());

// launch child with no inherited handles
PROCESS_INFORMATION procInfo;
ZeroMemory(&procInfo, sizeof(procInfo));
STARTUPINFOA startInfo;
ZeroMemory(&startInfo, sizeof(startInfo));
startInfo.cb = sizeof(startInfo);
startInfo.dwFlags |= STARTF_USESTDHANDLES;
bool success = CreateProcessA(NULL,
                              "test.exe",  // command line
                              NULL,     // process security attributes
                              NULL,   // primary thread security attributes
                              FALSE,  // handles are inherited
                              0,      // creation flags
                              NULL,   // use parent's environment
                              NULL,   // use parent's current directory
                              &startInfo,  // STARTUPINFO pointer
                              &procInfo);  // receives PROCESS_INFORMATION
// assign child to job
AssignProcessToJobObject(hJob, procInfo.hProcess);

这可行,但父应用程序和子应用程序(

main.exe
test.exe
)在任务管理器中显示为两个不相关的进程:

enter image description here

enter image description here

(即使关闭 main.exe 也会关闭 test.exe)。

我的做法与 Microsoft Teams 或 Chrome 等有嵌套流程的产品有何不同?

enter image description here

c++ windows winapi
3个回答
4
投票

任务管理器到底在做什么没有记录。

在 Windows 8 中,它不会对子进程进行分组,它仅根据具有窗口的进程或“特殊”进行组织。

任务管理器如何将进程分类为应用程序、后台进程或Windows进程?:

这些是任务管理器简单编造的术语。系统本身并不真正关心它们是什么类型的进程。

如果进程有可见窗口,则任务管理器将其称为“应用程序”。

如果进程被标记为关键,则任务管理器将其称为“Windows 进程”。

否则,任务管理器将其称为“后台进程”。

(我不相信这是 100% 准确的,它清楚地了解服务,我怀疑它可能会硬编码一些名称)

在 Windows 10 中,它更努力地将事物组合在一起,但我并不完全知道它在做什么。

  • 通常(但并非总是)能够将 conhost.exe 子进程绑定到其父控制台应用程序。

  • 记事本和画图的新奇特商店/打包版本将所有进程都放在一个组中。 Notepad2 不会发生同样的情况,即使它设置了应用程序模型 ID。它也不适用于写字板(即使一个是另一个的子代)。我还尝试在一个小测试应用程序中设置 AMUI,但进程范围的 AMUI 和每 HWND AMUI 似乎都不会触发分组。

  • 作业对象似乎未启用分组。

  • 根据您的版本,Edge 可能会使用特殊的 API 告诉任务管理器其进程

总之,我不知道它到底在寻找什么,但打包应用程序和应用程序容器似乎经常触发它。


2
投票

要使其在任务管理器中作为子进程可见,您必须在启动进程之前将 StartInfo 属性中的 CreateNoWindow 属性设置为 false,并将 UseShellExecute 属性设置为 false。

startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;

这告诉进程为子进程创建一个新窗口,并使用命令行来启动进程,而不是使用 shell 来启动进程。 现在,这将在任务管理器中创建子进程作为新的可见进程,并将显示在主进程的树下。


0
投票

最后找到解决办法了吗?

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