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

jfewjypa  于 2023-01-28  发布在  其他
关注(0)|答案(2)|浏览(301)

我有一个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.exetest.exe)在任务管理器中显示为两个不相关的进程:

(Even尽管关闭main.exe将关闭test.exe)。
我的做法与微软团队或Chrome有什么不同,它们都有嵌套的进程?

watbbzwu

watbbzwu1#

任务管理器的确切操作未记录。
在Windows 8中,它不会对子进程进行分组,它只会基于具有窗口的进程或通过"特殊"来组织。
How does Task Manager categorize processes as App, Background Process, or Windows Process?
这些都是任务管理器简单地创造出来的术语,系统本身并不真正关心它们是什么类型的进程。
如果进程具有可见窗口,则任务管理器将其称为"应用程序"。
如果进程被标记为关键,则任务管理器将其称为"Windows进程"。
否则,任务管理器将其称为"后台进程"。
(我不认为这是100%准确的,它清楚地知道服务,我怀疑它可能会硬编码一些名称)
在Windows 10中,它更努力地将东西组合在一起,但我不知道它到底在做什么。

  • 它通常(但不总是)能够将conhost.exe子应用程序绑定到其父控制台应用程序。
  • Notepad和Paint的新的花哨商店/打包版本将它们的所有进程都放在一个组中。Notepad2即使设置了应用程序模型ID,也不会发生同样的情况。它也不适用于写字板(即使其中一个是另一个的子进程)。我还尝试在一个小测试应用程序中设置AMUI,进程范围AMUI和每个HWND AMUI似乎都没有触发分组。
  • 作业对象似乎未启用分组。
  • 根据您的版本,Edge可能会使用特殊的API来执行tell Task manager about its processes

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

xqnpmsa8

xqnpmsa82#

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

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

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

相关问题