在看到 Win10 或 Win11 的 Task Manager 任务管理器时,不知大家是否有一个疑问,在 进程 标签里的应用进程是如何分组的。为什么有些组能包含很多个不同的进程,有些只能包含一个。本文将使用 WPF 写一个简单的应用来告诉大家任务管理器的进程分组策略

如下图,这是任务管理器看到的 VisualStudio 的界面,可以看到这个进程组里面包含很多个进程

那任务管理器将这些进程放在一个组里面的依据是什么?我能否可以将我自己的进程放在一个组里面,或者反过来我不想让我的进程放在一个组里面

在开始之前,需要说明的是,当前的任务管理器是不开源的,我也没有找到权威的文档来说这个事情,问了微软的大佬们,也没有收到回复。因此本文只能说是基于测试的结果了解任务管理器的行为。要是微软想不开,改了行为,那本文给出的分组策略也许就不对

任务管理器的分组依据是:

前台进程所直接启动的后台进程,将会放入到此前台进程所在的组里面

这里的前台进程指的是应用里面可以看到的进程,也是有带主窗口且显示的进程

前台进程所直接启动的后台进程的逻辑含义是此前台进程和对应的后台进程有父子进程关系

而后台进程指的是没有前台主窗口的进程,和是否控制台应用没有很大的关系,如果是控制台应用且有前台控制台窗口主机,依然不会被加入组内。或者说控制台应用存在前台主窗口,也不会被加入组内。也就是说只取决于是否存在前台主窗口,和是否控制台应用没有本质关系,即使是没有主窗口 GUI 应用,在这里也被当成后台进程

后台进程和前台进程之间是可以转换的,当前台进程没有前台主窗口时将转换为后台进程,当后台进程有前台主窗口时将转换为前台进程

另外继承链上的父子孙关系情况下,情况有些复杂,能否将孙进程显示在一个进程组里面,取决于子进程的存活时间,如果子进程在启动孙进程之后很快就退出,那么孙进程将不会被计入组里。如果子进程在启动孙进程之后,没有很快退出,那么孙进程将会被计入组里

以上的策略是我通过测试了解的,接下来将告诉大家这个测试应用的代码是如何编写的

先测试 前台进程所直接启动的后台进程,将会放入到此前台进程所在的组里面 的情况。测试方法就是通过一个带前台主窗口进程,启动另一个没有带前台主窗口的进程,看看在任务管理器里面是否放在一个组里面

新建一个叫 HakewofuCayorejar 的 WPF 应用,本文的代码基于 .NET 7 编写

为了方便代码编写,这里启动的多个进程都是相同的一个应用,只不过通过命令行参数决定不同的行为。为了更好的控制应用的逻辑,这里删除了 App.xaml 和 App.xaml.cs 文件,更改为自己编写 Main 函数

添加 Program 类,代码如下,用来在没有传入参数的时候,显示 MainWindow 作为前台主窗口。如果有命令行参数,那就啥都不做

static class Program
{
[STAThread]
static void Main(string[] args)
{
var application = new Application()
{
ShutdownMode = ShutdownMode.OnExplicitShutdown
};
application.Startup += (sender, eventArgs) =>
{
if (args.Length == 0)
{
var mainWindow = new MainWindow();
mainWindow.Show();
}
else
{
}
};
application.Run();
}
}

在 MainWindow 放一个按钮,点击按钮的时候,启动进程,传入参数

    private void Button_OnClick(object sender, RoutedEventArgs e)
{
var file = System.IO.Path.GetFullPath("HakewofuCayorejar.exe");
Process.Start(file, "xxxxx");
}

运行代码,然后点击按钮,接着看任务管理器,可以看到任务管理器里面的 HakewofuCayorejar 组将随着按钮的点击,可以看到越来越多的进程

再接着,关闭 HakewofuCayorejar 的 MainWindow 窗口,可以看到在任务管理器里面的应用刷新了,找不到 HakewofuCayorejar 组。只有在任务管理器的后台进程才能找到 HakewofuCayorejar 进程,这就证明了 HakewofuCayorejar 在关闭前台主窗口之后,从原本的前台进程转换为后台进程

再编辑一下代码测试任务管理器的更多行为,测试当一个后台进程转换为前台进程时的任务管理器行为情况,更改以上代码的 Program 代码,让带参数的进程等待几秒之后显示主窗口


static class Program
{
[STAThread]
static void Main(string[] args)
{
var application = new Application()
{
ShutdownMode = ShutdownMode.OnExplicitShutdown
};
application.Startup += (sender, eventArgs) =>
{
if (args.Length == 0)
{
var mainWindow = new MainWindow();
mainWindow.Show();
}
else
{
application.Dispatcher.InvokeAsync(async () =>
{
await Task.Delay(5000);
var mainWindow = new MainWindow();
mainWindow.Show();
});
}
};
application.Run();
}
}

运行代码,点击按钮,可以看到开始是将新的 HakewofuCayorejar 进程放入到第一个 HakewofuCayorejar 进程的组里面。但是等待一会,就可以看到任务管理器刷新了界面,拆开为两个 HakewofuCayorejar 组。这就证明了后台进程是可以通过显示前台主窗口转换为前台进程

接着测试父子孙进程的情况,测试孙进程是否被加入任务管理器的组里,取决于子进程在启动孙进程进程之后还能存在多久

更改 Program 的代码如下

static class Program
{
[STAThread]
static void Main(string[] args)
{
var application = new Application()
{
ShutdownMode = ShutdownMode.OnExplicitShutdown
};
application.Startup += async (sender, eventArgs) =>
{
if (args.Length == 0)
{
var mainWindow = new MainWindow();
mainWindow.Show();
}
else if (args.Length == 1)
{
var file = System.IO.Path.GetFullPath("HakewofuCayorejar.exe");
Process.Start(file, "xxxxx xxxxx");
await Task.Delay(10);
application.Shutdown();
}
};
application.Run();
}
}

让子进程使用两个参数启动孙进程,然后延迟 10 毫秒再退出

运行应用,不断点击按钮,让子进程启动孙进程。通过任务管理器可以看到,任务管理器的组里面有多少个进程,完全看任务管理器的心情或者说子进程的退出延迟。偶尔孙进程加入到组里面,偶尔孙进程没有加入组里面

本文的代码放在 githubgitee 欢迎访问

可以通过如下方式获取本文的源代码,先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin af83d991a8bc603d64501d27e8cf511b3cefbf81

以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin af83d991a8bc603d64501d27e8cf511b3cefbf81

获取代码之后,进入 HakewofuCayorejar 文件夹

WPF 探索任务管理器的进程分组逻辑的更多相关文章

  1. wpf 异常处理和关闭进程

    using System; using System.Collections.Generic; using System.Configuration; using System.Data; using ...

  2. C# 保护进程不被结束(源代码)防任务管理器结束进程

    C# 保护进程不被结束(源代码)防任务管理器结束进程 Posted on 2013-03-25 16:03 快乐家++ 阅读(3173) 评论(3) 编辑 收藏 闲来无事,英语又学的太痛苦.看到我妈妈 ...

  3. 理解WPF中的视觉树和逻辑树

    轉載地址:http://blog.csdn.net/changtianshuiyue/article/details/26981797 理解WPF中的视觉树和逻辑树  Understanding th ...

  4. WPF筛选、排序和分组

    可以通过CollectionViewSource或者CollectionView对视图进行排序.筛选和分组. 一.通过CollectionViewSource listingDataView是Coll ...

  5. 【windows】windows系统下,在任务管理器的进程选项卡中查看PID/任务管理器怎么查看PID

    PID,就是windows上的进程ID,是一个进程的唯一标识值. 那今天启动JDK跑起来一个项目之后,想要在任务管理器中查看这个JDK所在进程的PID但是看不到. 怎么解决? 1.我在任务管理器的服务 ...

  6. WPF知识点全攻略06- WPF逻辑树(Logical Tree)和可视树(Visual Tree)

    介绍概念之前,先来分析一段代码: xaml代码如下: <Window x:Class="WpfApp1.MainWindow" xmlns="http://sche ...

  7. Windows Server 2008 R2服务器内存使用率过高,但与任务管理器中进程占用内存和不一致

    系统环境: Windows Server 2008 R2 + Sql Server 2008 R2   问题描述: Windows Server 2008 R2系统内存占用率过大,而在任务管理器中各进 ...

  8. C#/WPF 仅启动一个进程实例

    如何实现仅启动一个 WPF 进程实例,并在打开第二个时,自动唤起之前打开的进程. 1 代码入口 在 App.xaml.cs 文件中,重写 OnStartup 方法,并添加 Mutex 进程锁. /// ...

  9. Nginx(二): worker 进程处理逻辑-流程框架

    Nginx 启动起来之后,会有几个进程运行:1. master 进程接收用户命令并做出响应; 2. worker 进程负责处理各网络事件,并同时接收来自master的处理协调命令: master 主要 ...

  10. C#程序双击运行之后,界面不显示,但是在任务管理器有进程(一个winform找bug之旅)

    最近客户端又出了奇葩事情:http://q.cnblogs.com/q/43038/ 如这篇博问一样.我的一个客户的电脑上程序打开了,进程也有了,就是界面窗体出不来!!! 我是win7是开发机,三四台 ...

随机推荐

  1. 记录--form 表单恢复初始数据

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 form 表单恢复初始数据 在现代的 Web 开发中,表单是不可或缺的组件之一.用户可以通过表单输入和提交数据,而开发者则需要对这些数据进 ...

  2. Clang Preprocessor 类的创建

    参考: Create a working compiler with the LLVM framework, Part 2 How to parse C programs with Clang: A ...

  3. ForkJoinPool在生产环境中使用遇到的一个问题

    1.背景 在我们的项目中有这么一个场景,需要消费kafka中的消息,并生成对应的工单数据.早些时候程序运行的好好的,但是有一天,我们升级了容器的配置,结果导致部分消息无法消费.而消费者的代码是使用Co ...

  4. KingbaseESV8R6用户登录失败自动锁定后解锁遇到权限问题

    测试用户登录失败自动锁定 创建用户tee并授权. TEST=# create user tee; CREATE ROLE TEST=# alter user tee with createdb; AL ...

  5. 开源车牌识别系统HyperLPR踩坑

    项目地址 https://github.com/zeusees/HyperLPR python配置参考文章 https://www.jianshu.com/p/7ab673abeaae 安装Anaco ...

  6. Spring boot中拦截器的简单使用

    1.创建自定义拦截器类:首先,你需要创建一个自定义的拦截器类,该类需要实现HandlerInterceptor接口.例如,你可以创建一个名为CustomInterceptor的类. import or ...

  7. #线段树#LOJ 6029「雅礼集训 2017 Day1」市场

    题目 在长度为\(n(n\leq 10^5)\)的数列中, 需要满足区间加,区间下取整的操作 以及能够查询区间和以及区间最小值 除数\(d\)满足\(2\leq d\leq 10^9\) 加数\(c\ ...

  8. OpenHarmony社区运营报告(2023年2月)

      本月快讯 • 2023年2月25日,以"技术构筑万物智联"为主题的第一届开放原子开源基金会OpenAtom OpenHarmony(以下简称"OpenHarmony& ...

  9. Linux系统奇安信浏览器报错跨域:the resource is in more-private address space 'local'

    报错: Access to XMLHttpRequest at "123" from origin "456" has been blocked by CORS ...

  10. 知识图谱增强的KG-RAG框架

    昨天我们聊到KG在RAG中如何发挥作用,今天我们来看一个具体的例子. 我们找到一篇论文: https://arxiv.org/abs/2311.17330 ,论文的研究人员开发了一种名为知识图谱增强的 ...