NETworkManager源码剖析:一个网络管理工具的实现细节

在 GitHub 闲逛时,我偶然发现了NETworkManager这个开源项目。作为一款网络管理和故障排查工具,它已经积累了超过 8.5k Star,足以说明社区对它的认可。更让我感兴趣的是,这个项目采用 C# + WPF 进行开发,与我当前正在深入学习和实践的技术栈高度契合。因此,我产生了一个想法:通过深入分析 NETworkManager 的源码,探索一个成熟的 WPF 桌面应用是如何进行架构设计、模块划分以及工程实践的。接下来,我将以 NETworkManager 为切入点,逐步拆解它在 WPF UI 设计、MVVM 架构、依赖注入、配置管理、网络通信、异步编程以及工程化实践 等方面的实现,希望能够从优秀的开源项目中学习桌面应用开发的最佳实践。
|
|
将项目Clone到本地,整个解决方案结构如下:

解决方案下包含了多个子项目,说明将实现逻辑进行了合理拆分,进行了模块化设计。
1. NETworkManager启动时,到底发生了什么?
WPF应用生命周期大致如下:
flowchart TD
A[Application_Startup] --> B[创建Window]
B --> C[用户正常使用]
C --> D[Application_Exit]
D --> E[程序结束]
flowchart TD
A[Application_Startup] --> B[创建Window]
B --> C[用户正常使用]
C --> D[Application_Exit]
D --> E[程序结束]
flowchart TD
A[Application_Startup] --> B[创建Window]
B --> C[用户正常使用]
C --> D[Application_Exit]
D --> E[程序结束]
|
|
在Visual Studio 2026按F5调试启动后,首先映入眼帘的是启动画面窗口:

接着就会出现隐私政策设置界面:

点击“继续”后就进入到了主界面(仪表盘):

NETworkManager项目的App.xaml.cs中包含了软件启动时的逻辑,里面主要包含了Application_Startup、OnSessionEnding、Application_Exit和Save等4个方法。
Application_Startup
设置了全局异常捕获:
|
|
等待旧进程退出:
|
|
单实例检测:
|
|
防止用户点击两次exe,两个程序运行。第一次创建Mutex成功,第二次创建Mutex失败。于是:
|
|
接下来会显示启动画面窗口和主窗口:
|
|
启动流程如下:
flowchart TD
A[Application_Startup] --> B[启动日志]
B --> C[异常捕获]
C --> D[检查旧实例]
D --> E[加载Policy]
E --> F[加载Settings]
F --> G[升级配置]
G --> H[初始化语言]
H --> I[单实例检测]
I --> J[启动后台任务]
J --> K[调整线程池]
K --> L[SplashScreen]
L --> M[MainWindow]
flowchart TD
A[Application_Startup] --> B[启动日志]
B --> C[异常捕获]
C --> D[检查旧实例]
D --> E[加载Policy]
E --> F[加载Settings]
F --> G[升级配置]
G --> H[初始化语言]
H --> I[单实例检测]
I --> J[启动后台任务]
J --> K[调整线程池]
K --> L[SplashScreen]
L --> M[MainWindow]
flowchart TD
A[Application_Startup] --> B[启动日志]
B --> C[异常捕获]
C --> D[检查旧实例]
D --> E[加载Policy]
E --> F[加载Settings]
F --> G[升级配置]
G --> H[初始化语言]
H --> I[单实例检测]
I --> J[启动后台任务]
J --> K[调整线程池]
K --> L[SplashScreen]
L --> M[MainWindow]
|
|
Policy从exe所在目录的config.json加载,而LocalSettings从用户家目录\\AppData\\Local\\NETworkManager\\Settings.json文件加载,Settings从用户家目录\\Documents\\NETworkManager\\Settings\\Settings.json文件加载。
Application_Exit
Application_Exit会在应用退出时调用,主要调用了Save,在退出时保存程序设置和配置文件。
Save
Save如果检测到更改,会保存应用程序设置和配置文件数据。
OnSessionEnding
OnSessionEnding会在Windows注销或者Windows关机时被调用。
2. 日志保存在什么位置?
NETworkerManager使用的是log4net日志库。在项目的根目录下有一个log4net.config文件用于配置日志:
|
|
日志保存在${LocalAppData}\\NETworkManager目录中。
3. 仪表盘界面中的IP地址是如何获取的?
如4所示,仪表盘界面中的IPv4、IPv6以及DNS地址是如何获取的呢?ViewModels/NetworkConnectionWidgetViewModel.cs可以找到答案。
相关内容
- Downloader源码剖析:一个下载器的实现原理
- DotNetty源码剖析:高性能网络框架的秘密
- Requests源码剖析:优雅发送HTTP请求实现原理
- Hugo源码剖析:世界最快静态站点生成器的实现原理
- Redis源码剖析:一个高性能服务器的设计哲学
- LevelDB源码剖析:Google如何设计一个高性能嵌入式数据库
- C#高效编程 改进C#代码的50个行之有效的办法 第2版 (Bill Wagner)
- Shadowsocks源码剖析:一个轻量级代理工具背后的网络编程设计
- Node.js 源码剖析:非阻塞世界的引擎密码
- CPython 源码剖析:Python 运行的奥秘
- launch-editor源码剖析:快速打开编辑器的实现原理
- json-server源码剖析:快速构建REST API背后的原理
- csv2 源码剖析:轻量级 CSV 处理的高效之道
- C#中的nameof运算符
支付宝
微信