在看到 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. 记录--分享并解析一个倒计时组件(Vue)

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 一.前言 入职的第一个需求是跟着一位前端大佬一起完成的一个活动项目. 由于是一起开发,当然不会放过阅读大佬的代码的机会. 因为我的页面中需 ...

  2. 记录--原生 canvas 如何实现大屏?

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前言 可视化大屏该如何做?有可能一天完成吗?废话不多说,直接看效果,线上 Demo 地址 lxfu1.github.io/large-sc ...

  3. ConnectionResetError: [WinError 10054] 远程主机强迫关闭了一个现有的连接

    ConnectionResetError: [WinError 10054] 远程主机强迫关闭了一个现有的连接 是因为使用urlopen方法太过频繁,引起远程主机的怀疑,被网站认定为是攻击行为.导致u ...

  4. C# OpenCvSharp+ 微信二维码引擎实现二维码识别

    微信开源了其二维码的解码功能,并贡献给 OpenCV 社区.其开源的 wechat_qrcode 项目被收录到 OpenCV contrib 项目中.从 OpenCV 4.5.2 版本开始,就可以直接 ...

  5. FPGA中与时序有关的概念

    FPGA中与时序有关的概念 一.时序分析 时序分析是对整个时序进行分析的操作.作用就是了解设计的时序性能,一般而言就是最大时钟频率.时钟频率越高,设计的工作速度越快(忽略设计实现方法的不同导致的效率提 ...

  6. KingbaseES 实现 MYSQL 的 delete limit 写法

    使用MySQL的用户可能会比较熟悉这样的用法,更新或删除时可以指定限制更新或删除多少条记录. update tl set xxx=xxx where xxx limit 10; delete from ...

  7. IntelliJ IDEA 设置类和方法注释

    一.在创建类和文件的时候加注释 1.创建类 在右侧输入: 1 /** 2 * 3 * @author ${USER} 4 * @date ${YEAR}-${MONTH}-${DAY} ${TIME} ...

  8. .NetCore HttpClient Proxy 设置全局代理

    .NetCore HttpClient Proxy 设置全局代理 环境 .net6.0,使用的是 HttpClient 在Program.cs里面 service.AddHttpClient<H ...

  9. SC的板子库~

    观前须知 Sugar_Cube的博客园主页 声明 本文所有内容遵循CC BY-NC-SA 4.0 Deed原则 本文包含了笔者常用的OI算法.数据结构的模板 不保证算法最优,但能通过相应的模板题(如果 ...

  10. 使用8086汇编驱动SHT11传感器

    前言:使用Proteus 7.8仿真软件实现8086接入SHT11温湿度传感器(实现读取温度数据部分功能),并学习如何在没有集成硬件控制下串行总线的驱动方式,汇编的精髓就是寄存器的操作.各种寻址方式. ...