mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-24 02:14:26 +08:00
381 lines
8.5 KiB
Markdown
381 lines
8.5 KiB
Markdown
|
|
# 04-调试运行指南
|
|||
|
|
|
|||
|
|
掌握插件调试技巧,能大幅提升开发效率。本文介绍阑山桌面插件的各种调试方法和常见问题排查。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔄 调试方式概述
|
|||
|
|
|
|||
|
|
阑山桌面插件有两种主要调试方式:
|
|||
|
|
|
|||
|
|
| 方式 | 适用场景 | 优点 | 缺点 |
|
|||
|
|
|-----|---------|------|------|
|
|||
|
|
| **附加到进程** | 日常开发调试 | 不改变项目结构 | 每次需手动附加 |
|
|||
|
|
| **独立调试** | 深度调试、单元测试 | 启动即调试 | 配置较复杂 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🎯 方式一:附加到进程(推荐)
|
|||
|
|
|
|||
|
|
这是日常开发中最常用的调试方式。
|
|||
|
|
|
|||
|
|
### 步骤
|
|||
|
|
|
|||
|
|
1. **启动阑山桌面**
|
|||
|
|
- 正常启动宿主应用(非调试模式)
|
|||
|
|
- 确保你的插件已安装
|
|||
|
|
|
|||
|
|
2. **在 IDE 中打开插件项目**
|
|||
|
|
- 使用 Visual Studio / Rider / VS Code 打开项目
|
|||
|
|
|
|||
|
|
3. **设置断点**
|
|||
|
|
- 在你想要调试的代码行左侧点击,设置断点
|
|||
|
|
- 常见断点位置:
|
|||
|
|
- `Plugin.Initialize()` - 插件初始化
|
|||
|
|
- 组件构造函数
|
|||
|
|
- 设置页面加载方法
|
|||
|
|
|
|||
|
|
4. **附加到进程**
|
|||
|
|
|
|||
|
|
**Visual Studio:**
|
|||
|
|
- 菜单:`调试` → `附加到进程`
|
|||
|
|
- 或快捷键:`Ctrl+Alt+P`
|
|||
|
|
- 在列表中找到 `LanMountainDesktop.exe`
|
|||
|
|
- 点击`附加`
|
|||
|
|
|
|||
|
|
**Rider:**
|
|||
|
|
- 菜单:`Run` → `Attach to Process`
|
|||
|
|
- 或快捷键:`Ctrl+Alt+F5`
|
|||
|
|
- 选择 `LanMountainDesktop.exe`
|
|||
|
|
|
|||
|
|
**VS Code:**
|
|||
|
|
- 按 `Ctrl+Shift+D` 打开调试面板
|
|||
|
|
- 点击`创建 launch.json 文件`
|
|||
|
|
- 选择 `.NET Core Attach`
|
|||
|
|
- 选择 `LanMountainDesktop` 进程
|
|||
|
|
|
|||
|
|
5. **触发调试**
|
|||
|
|
- 在阑山桌面中操作,触发插件代码
|
|||
|
|
- 例如:添加组件、打开设置页面等
|
|||
|
|
- 程序会在断点处暂停
|
|||
|
|
|
|||
|
|
### 附加配置(VS Code)
|
|||
|
|
|
|||
|
|
创建 `.vscode/launch.json`:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"version": "0.2.0",
|
|||
|
|
"configurations": [
|
|||
|
|
{
|
|||
|
|
"name": "附加到阑山桌面",
|
|||
|
|
"type": "coreclr",
|
|||
|
|
"request": "attach",
|
|||
|
|
"processName": "LanMountainDesktop"
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔧 方式二:独立调试
|
|||
|
|
|
|||
|
|
适用于深度调试或单元测试。
|
|||
|
|
|
|||
|
|
### 配置步骤
|
|||
|
|
|
|||
|
|
1. **修改 .csproj 临时引用宿主**
|
|||
|
|
|
|||
|
|
```xml
|
|||
|
|
<ItemGroup>
|
|||
|
|
<!-- 临时添加,仅用于调试 -->
|
|||
|
|
<ProjectReference Include="..\LanMountainDesktop\LanMountainDesktop.csproj" />
|
|||
|
|
</ItemGroup>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
2. **创建调试启动配置**
|
|||
|
|
|
|||
|
|
**Visual Studio:**
|
|||
|
|
- 右键项目 → `属性` → `调试`
|
|||
|
|
- 启动外部程序:选择 `LanMountainDesktop.exe`
|
|||
|
|
- 工作目录:设为宿主输出目录
|
|||
|
|
|
|||
|
|
**VS Code launch.json:**
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"version": "0.2.0",
|
|||
|
|
"configurations": [
|
|||
|
|
{
|
|||
|
|
"name": "启动阑山桌面(调试)",
|
|||
|
|
"type": "coreclr",
|
|||
|
|
"request": "launch",
|
|||
|
|
"program": "${workspaceFolder}/../LanMountainDesktop/bin/Debug/net10.0/LanMountainDesktop.exe",
|
|||
|
|
"args": [],
|
|||
|
|
"cwd": "${workspaceFolder}/../LanMountainDesktop/bin/Debug/net10.0",
|
|||
|
|
"stopAtEntry": false
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
3. **启动调试**
|
|||
|
|
- 按 `F5` 启动
|
|||
|
|
- 宿主会以调试模式启动
|
|||
|
|
- 插件代码中的断点会直接命中
|
|||
|
|
|
|||
|
|
⚠️ **注意:** 发布插件前务必移除临时引用!
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📝 日志调试
|
|||
|
|
|
|||
|
|
当断点调试不方便时,日志是最有效的调试手段。
|
|||
|
|
|
|||
|
|
### 使用 ILogger
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
using Microsoft.Extensions.Logging;
|
|||
|
|
|
|||
|
|
public class MyService
|
|||
|
|
{
|
|||
|
|
private readonly ILogger<MyService> _logger;
|
|||
|
|
|
|||
|
|
public MyService(ILogger<MyService> logger)
|
|||
|
|
{
|
|||
|
|
_logger = logger;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void DoWork()
|
|||
|
|
{
|
|||
|
|
_logger.LogInformation("开始执行任务");
|
|||
|
|
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
// 业务逻辑
|
|||
|
|
_logger.LogDebug("处理数据: {Data}", data);
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
_logger.LogError(ex, "任务执行失败");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
_logger.LogInformation("任务完成");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 日志级别
|
|||
|
|
|
|||
|
|
| 级别 | 使用场景 |
|
|||
|
|
|-----|---------|
|
|||
|
|
| `LogTrace` | 最详细的跟踪信息 |
|
|||
|
|
| `LogDebug` | 调试信息 |
|
|||
|
|
| `LogInformation` | 一般信息 |
|
|||
|
|
| `LogWarning` | 警告信息 |
|
|||
|
|
| `LogError` | 错误信息 |
|
|||
|
|
| `LogCritical` | 严重错误 |
|
|||
|
|
|
|||
|
|
### 查看日志文件
|
|||
|
|
|
|||
|
|
日志文件位置:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Windows: %LOCALAPPDATA%\LanMountainDesktop\logs\
|
|||
|
|
Linux: ~/.local/share/LanMountainDesktop/logs/
|
|||
|
|
macOS: ~/Library/Application Support/LanMountainDesktop/logs/
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
日志文件命名格式:
|
|||
|
|
```
|
|||
|
|
log-20240413.txt
|
|||
|
|
log-20240413_001.txt
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 实时查看日志
|
|||
|
|
|
|||
|
|
**Windows PowerShell:**
|
|||
|
|
```powershell
|
|||
|
|
Get-Content "$env:LOCALAPPDATA\LanMountainDesktop\logs\log-$(Get-Date -Format 'yyyyMMdd').txt" -Wait
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Linux/macOS:**
|
|||
|
|
```bash
|
|||
|
|
tail -f ~/.local/share/LanMountainDesktop/logs/log-$(date +%Y%m%d).txt
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🚫 热重载限制
|
|||
|
|
|
|||
|
|
⚠️ **重要:** 阑山桌面插件**不支持**热重载(Hot Reload)
|
|||
|
|
|
|||
|
|
### 原因
|
|||
|
|
|
|||
|
|
插件运行在独立的 `AssemblyLoadContext` 中,.NET 不支持卸载已加载的程序集。因此:
|
|||
|
|
|
|||
|
|
- 修改代码后必须重新构建
|
|||
|
|
- 必须重启宿主才能加载新版本
|
|||
|
|
- 无法使用 `dotnet watch`
|
|||
|
|
|
|||
|
|
### 高效开发流程
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
修改代码 → dotnet build → 重启宿主 → 测试
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**加速技巧:**
|
|||
|
|
|
|||
|
|
1. **创建批处理脚本**(`rebuild-and-run.ps1`):
|
|||
|
|
```powershell
|
|||
|
|
dotnet build
|
|||
|
|
Stop-Process -Name "LanMountainDesktop" -ErrorAction SilentlyContinue
|
|||
|
|
Start-Process "C:\Path\To\LanMountainDesktop.exe"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
2. **使用 Rider 的外部工具**:
|
|||
|
|
- 配置构建后自动复制 `.laapp` 到插件目录
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🐛 常见问题排查
|
|||
|
|
|
|||
|
|
### 问题 1:断点不命中
|
|||
|
|
|
|||
|
|
**可能原因:**
|
|||
|
|
- 插件未重新构建
|
|||
|
|
- PDB 符号文件未生成
|
|||
|
|
- 附加到了错误的进程
|
|||
|
|
|
|||
|
|
**解决步骤:**
|
|||
|
|
1. 确认已重新构建:`dotnet build`
|
|||
|
|
2. 检查输出目录是否有 `.pdb` 文件
|
|||
|
|
3. 确认附加的是 `LanMountainDesktop.exe`(不是 `LanMountainDesktop.dll`)
|
|||
|
|
4. 尝试清理重建:
|
|||
|
|
```powershell
|
|||
|
|
dotnet clean
|
|||
|
|
dotnet build
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 问题 2:插件不加载
|
|||
|
|
|
|||
|
|
**排查步骤:**
|
|||
|
|
|
|||
|
|
1. **检查日志**
|
|||
|
|
```powershell
|
|||
|
|
Get-Content "$env:LOCALAPPDATA\LanMountainDesktop\logs\log-$(Get-Date -Format 'yyyyMMdd').txt" | Select-String "MyPlugin"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
2. **验证 plugin.json**
|
|||
|
|
- JSON 格式是否有效
|
|||
|
|
- `id` 是否合法(只含小写字母、数字、点号)
|
|||
|
|
- `apiVersion` 是否与 SDK 版本匹配
|
|||
|
|
|
|||
|
|
3. **检查 .laapp 包**
|
|||
|
|
- 用压缩软件打开,确认文件完整
|
|||
|
|
- 确认 `plugin.json` 和 DLL 存在
|
|||
|
|
|
|||
|
|
### 问题 3:依赖项找不到
|
|||
|
|
|
|||
|
|
**现象:** `FileNotFoundException` 或 `Could not load file or assembly`
|
|||
|
|
|
|||
|
|
**解决:**
|
|||
|
|
1. 确保所有依赖项都复制到输出目录
|
|||
|
|
2. 在 `.csproj` 中添加:
|
|||
|
|
```xml
|
|||
|
|
<PropertyGroup>
|
|||
|
|
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
|||
|
|
</PropertyGroup>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 问题 4:调试时宿主卡顿
|
|||
|
|
|
|||
|
|
**原因:** 断点暂停导致 UI 线程阻塞
|
|||
|
|
|
|||
|
|
**解决:**
|
|||
|
|
- 使用 `Debugger.Break()` 代替断点
|
|||
|
|
- 或使用日志代替断点调试
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 💡 调试技巧
|
|||
|
|
|
|||
|
|
### 1. 条件断点
|
|||
|
|
|
|||
|
|
当需要在特定条件下暂停时使用:
|
|||
|
|
|
|||
|
|
**Visual Studio:**
|
|||
|
|
- 右键断点 → `条件`
|
|||
|
|
- 输入条件表达式,如:`count > 10`
|
|||
|
|
|
|||
|
|
### 2. 日志点(Tracepoint)
|
|||
|
|
|
|||
|
|
不暂停程序,只输出日志:
|
|||
|
|
|
|||
|
|
**Visual Studio:**
|
|||
|
|
- 右键断点 → `操作`
|
|||
|
|
- 勾选 `将消息输出到输出窗口`
|
|||
|
|
- 输入消息模板:`变量值: {variableName}`
|
|||
|
|
|
|||
|
|
### 3. 异常设置
|
|||
|
|
|
|||
|
|
自动在抛出异常时中断:
|
|||
|
|
|
|||
|
|
**Visual Studio:**
|
|||
|
|
- `调试` → `窗口` → `异常设置`
|
|||
|
|
- 勾选 `Common Language Runtime Exceptions`
|
|||
|
|
|
|||
|
|
### 4. 立即窗口
|
|||
|
|
|
|||
|
|
在调试时执行代码:
|
|||
|
|
|
|||
|
|
**Visual Studio:**
|
|||
|
|
- 快捷键:`Ctrl+Alt+I`
|
|||
|
|
- 可查看变量值、调用方法
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📊 性能调试
|
|||
|
|
|
|||
|
|
### 使用 Diagnostic Tools
|
|||
|
|
|
|||
|
|
**Visual Studio:**
|
|||
|
|
- 调试时自动显示 CPU 和内存使用情况
|
|||
|
|
- `调试` → `窗口` → `诊断工具`
|
|||
|
|
|
|||
|
|
### 内存泄漏排查
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// 在可疑位置添加诊断代码
|
|||
|
|
GC.Collect();
|
|||
|
|
GC.WaitForPendingFinalizers();
|
|||
|
|
GC.Collect();
|
|||
|
|
var memory = GC.GetTotalMemory(true);
|
|||
|
|
Debug.WriteLine($"内存使用: {memory / 1024 / 1024} MB");
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🎯 下一步
|
|||
|
|
|
|||
|
|
掌握了调试技巧后,接下来学习核心概念:
|
|||
|
|
|
|||
|
|
👉 **[01-插件生命周期](../02-核心概念与原理/01-插件生命周期.md)** - 理解插件运行机制
|
|||
|
|
|
|||
|
|
或者查看实战案例:
|
|||
|
|
|
|||
|
|
👉 **[01-开发天气组件](../04-实战案例/01-开发天气组件.md)** - 完整开发流程
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📚 参考资源
|
|||
|
|
|
|||
|
|
- [PluginBase 源码](../../LanMountainDesktop.PluginSdk/PluginBase.cs)
|
|||
|
|
- [docs/DEVELOPMENT.md](../../docs/DEVELOPMENT.md)
|
|||
|
|
- [Visual Studio 调试文档](https://docs.microsoft.com/visualstudio/debugger/)
|
|||
|
|
- [Rider 调试文档](https://www.jetbrains.com/help/rider/Debugging.html)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
*最后更新:2026年4月*
|