Files

351 lines
9.2 KiB
Markdown
Raw Permalink Normal View History

2026-04-13 19:54:37 +08:00
# 03-插件项目结构详解
了解插件项目的每个文件和文件夹的作用,是开发高质量插件的基础。本文将详细解析插件项目的完整结构。
---
## 📂 项目结构概览
使用模板创建的插件项目结构如下:
```
MyPlugin/
├── plugin.json # 插件清单(必需)
├── MyPlugin.csproj # 项目文件(必需)
├── Plugin.cs # 入口类(必需)
├── README.md # 项目说明(推荐)
├── .gitignore # Git忽略文件可选
└── Localization/ # 本地化文件夹(可选)
├── zh-CN.json # 中文资源
└── en-US.json # 英文资源
```
---
## 📋 plugin.json - 插件清单
这是插件最重要的配置文件,定义了插件的元数据。
### 完整示例
```json
{
"id": "com.example.myplugin",
"name": "我的插件",
"description": "这是一个示例插件",
"author": "作者名称",
"version": "1.0.0",
Avalonia12 (#7) * ava12升级 * Enable centralized package versioning Add <Project> and <PropertyGroup> with <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally> to Directory.Packages.props to enable centralized package version management across the repository. This allows package versions to be controlled from this single file instead of individual project files. * Migrate codebase to Avalonia 12 APIs Apply Avalonia 12 migration changes: replace SystemDecorations with WindowDecorations and remove ExtendClientAreaChromeHints/ExtendClientAreaTitleBarHeightHint usages; update BindingPlugins removal logic (no-op); switch clipboard usage to ClipboardExtensions.SetTextAsync; update Bitmap.CopyPixels calls to the new signature. Replace TextBox.Watermark with PlaceholderText, convert NumberBox styles to FANumberBox and adjust templates, change Checked/Unchecked handlers to IsCheckedChanged, and adapt FluentIcons usages (SymbolIconSource -> FASymbol/FAFont/FluentIcon equivalents). Fix MainWindow partial classes to inherit Window and correct missing variables/fields/usings. Add migration docs/specs/tasks under .trae and include a small TestFluentIcons project for icon testing. * Migrate to Avalonia 12 and Plugin SDK v5 Upgrade project to the Avalonia 12 baseline and Plugin SDK v5: centralize Avalonia packages, remove legacy WebView.Avalonia usage (use NativeWebView/WebView2 EnvironmentRequested), and update Fluent/Material icon/package usages. Bump multiple package/project versions to 5.0.0 and Avalonia 12.0.1, update plugin template and README/docs to SDK v5, and add PLUGIN_SDK_V5_MIGRATION.md. Also fix runtime/behavior bugs: make DataLocationResolver use a fixed bootstrap launcher data path and avoid recursive ResolveDataRoot; add legacy-state handling and extraction in OobeStateService; and update component settings tests to reflect migrated storage (DB/backup) and reset cache for test reloads. Various csproj, tests, and docs updated to reflect the migration and ensure build/test compatibility. * Update icon glyphs and symbol mappings Replace and refine icon sources across settings pages and controls: many FAFontIconSource glyphs were updated to specific Seagull Fluent Icons codepoints, some FASymbolIconSource usages were replaced with FAFontIconSource, and a number of symbol-to-Symbol enum mappings were adjusted (e.g. "Bell" -> AlertOn, "Shield" -> ShieldLock). Also clarified a comment in SettingsWindow and fixed a trailing newline in StudySettingsPage. Changes standardize icon visuals and bridge FluentIcons glyphs into FluentAvalonia icon sources. * fix.修复合并产生的问题。
2026-04-29 12:14:29 +08:00
"apiVersion": "5.0.0",
2026-04-13 19:54:37 +08:00
"entranceAssembly": "MyPlugin.dll",
"sharedContracts": [],
"website": "https://example.com",
"icon": "icon.png",
"tags": ["工具", "实用"]
}
```
### 字段详解
| 字段 | 必需 | 说明 | 示例 |
|-----|------|------|------|
| `id` | ✅ | 唯一标识符,反向域名格式 | `com.yourname.plugin` |
| `name` | ✅ | 显示名称 | `天气插件` |
| `description` | ✅ | 简短描述 | `显示实时天气信息` |
| `author` | ✅ | 作者名称 | `张三` |
| `version` | ✅ | 版本号(语义化版本) | `1.0.0` |
Avalonia12 (#7) * ava12升级 * Enable centralized package versioning Add <Project> and <PropertyGroup> with <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally> to Directory.Packages.props to enable centralized package version management across the repository. This allows package versions to be controlled from this single file instead of individual project files. * Migrate codebase to Avalonia 12 APIs Apply Avalonia 12 migration changes: replace SystemDecorations with WindowDecorations and remove ExtendClientAreaChromeHints/ExtendClientAreaTitleBarHeightHint usages; update BindingPlugins removal logic (no-op); switch clipboard usage to ClipboardExtensions.SetTextAsync; update Bitmap.CopyPixels calls to the new signature. Replace TextBox.Watermark with PlaceholderText, convert NumberBox styles to FANumberBox and adjust templates, change Checked/Unchecked handlers to IsCheckedChanged, and adapt FluentIcons usages (SymbolIconSource -> FASymbol/FAFont/FluentIcon equivalents). Fix MainWindow partial classes to inherit Window and correct missing variables/fields/usings. Add migration docs/specs/tasks under .trae and include a small TestFluentIcons project for icon testing. * Migrate to Avalonia 12 and Plugin SDK v5 Upgrade project to the Avalonia 12 baseline and Plugin SDK v5: centralize Avalonia packages, remove legacy WebView.Avalonia usage (use NativeWebView/WebView2 EnvironmentRequested), and update Fluent/Material icon/package usages. Bump multiple package/project versions to 5.0.0 and Avalonia 12.0.1, update plugin template and README/docs to SDK v5, and add PLUGIN_SDK_V5_MIGRATION.md. Also fix runtime/behavior bugs: make DataLocationResolver use a fixed bootstrap launcher data path and avoid recursive ResolveDataRoot; add legacy-state handling and extraction in OobeStateService; and update component settings tests to reflect migrated storage (DB/backup) and reset cache for test reloads. Various csproj, tests, and docs updated to reflect the migration and ensure build/test compatibility. * Update icon glyphs and symbol mappings Replace and refine icon sources across settings pages and controls: many FAFontIconSource glyphs were updated to specific Seagull Fluent Icons codepoints, some FASymbolIconSource usages were replaced with FAFontIconSource, and a number of symbol-to-Symbol enum mappings were adjusted (e.g. "Bell" -> AlertOn, "Shield" -> ShieldLock). Also clarified a comment in SettingsWindow and fixed a trailing newline in StudySettingsPage. Changes standardize icon visuals and bridge FluentIcons glyphs into FluentAvalonia icon sources. * fix.修复合并产生的问题。
2026-04-29 12:14:29 +08:00
| `apiVersion` | ✅ | SDK API 版本 | `5.0.0` |
2026-04-13 19:54:37 +08:00
| `entranceAssembly` | ✅ | 入口程序集文件名 | `MyPlugin.dll` |
| `sharedContracts` | ✅ | 共享契约类型列表 | `[]` |
| `website` | ❌ | 项目网站 | `https://github.com/...` |
| `icon` | ❌ | 图标文件名 | `icon.png` |
| `tags` | ❌ | 标签数组 | `["天气", "工具"]` |
### 重要规则
⚠️ **id 字段规则:**
- 只能包含小写字母、数字、点号(`.`
- 必须全局唯一
- 建议使用反向域名格式:`com.yourname.pluginname`
- 一经发布不可更改
⚠️ **version 字段规则:**
- 使用语义化版本格式:`主版本.次版本.修订号`
- 示例:`1.0.0``2.1.3-beta`
⚠️ **apiVersion 字段规则:**
- 必须与引用的 SDK 版本兼容
Avalonia12 (#7) * ava12升级 * Enable centralized package versioning Add <Project> and <PropertyGroup> with <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally> to Directory.Packages.props to enable centralized package version management across the repository. This allows package versions to be controlled from this single file instead of individual project files. * Migrate codebase to Avalonia 12 APIs Apply Avalonia 12 migration changes: replace SystemDecorations with WindowDecorations and remove ExtendClientAreaChromeHints/ExtendClientAreaTitleBarHeightHint usages; update BindingPlugins removal logic (no-op); switch clipboard usage to ClipboardExtensions.SetTextAsync; update Bitmap.CopyPixels calls to the new signature. Replace TextBox.Watermark with PlaceholderText, convert NumberBox styles to FANumberBox and adjust templates, change Checked/Unchecked handlers to IsCheckedChanged, and adapt FluentIcons usages (SymbolIconSource -> FASymbol/FAFont/FluentIcon equivalents). Fix MainWindow partial classes to inherit Window and correct missing variables/fields/usings. Add migration docs/specs/tasks under .trae and include a small TestFluentIcons project for icon testing. * Migrate to Avalonia 12 and Plugin SDK v5 Upgrade project to the Avalonia 12 baseline and Plugin SDK v5: centralize Avalonia packages, remove legacy WebView.Avalonia usage (use NativeWebView/WebView2 EnvironmentRequested), and update Fluent/Material icon/package usages. Bump multiple package/project versions to 5.0.0 and Avalonia 12.0.1, update plugin template and README/docs to SDK v5, and add PLUGIN_SDK_V5_MIGRATION.md. Also fix runtime/behavior bugs: make DataLocationResolver use a fixed bootstrap launcher data path and avoid recursive ResolveDataRoot; add legacy-state handling and extraction in OobeStateService; and update component settings tests to reflect migrated storage (DB/backup) and reset cache for test reloads. Various csproj, tests, and docs updated to reflect the migration and ensure build/test compatibility. * Update icon glyphs and symbol mappings Replace and refine icon sources across settings pages and controls: many FAFontIconSource glyphs were updated to specific Seagull Fluent Icons codepoints, some FASymbolIconSource usages were replaced with FAFontIconSource, and a number of symbol-to-Symbol enum mappings were adjusted (e.g. "Bell" -> AlertOn, "Shield" -> ShieldLock). Also clarified a comment in SettingsWindow and fixed a trailing newline in StudySettingsPage. Changes standardize icon visuals and bridge FluentIcons glyphs into FluentAvalonia icon sources. * fix.修复合并产生的问题。
2026-04-29 12:14:29 +08:00
- 当前最新版本:`5.0.0`
2026-04-13 19:54:37 +08:00
- 不兼容时宿主将拒绝加载插件
---
## 🔧 .csproj - 项目文件
定义了项目的构建配置和依赖项。
### 完整示例
```xml
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
Avalonia12 (#7) * ava12升级 * Enable centralized package versioning Add <Project> and <PropertyGroup> with <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally> to Directory.Packages.props to enable centralized package version management across the repository. This allows package versions to be controlled from this single file instead of individual project files. * Migrate codebase to Avalonia 12 APIs Apply Avalonia 12 migration changes: replace SystemDecorations with WindowDecorations and remove ExtendClientAreaChromeHints/ExtendClientAreaTitleBarHeightHint usages; update BindingPlugins removal logic (no-op); switch clipboard usage to ClipboardExtensions.SetTextAsync; update Bitmap.CopyPixels calls to the new signature. Replace TextBox.Watermark with PlaceholderText, convert NumberBox styles to FANumberBox and adjust templates, change Checked/Unchecked handlers to IsCheckedChanged, and adapt FluentIcons usages (SymbolIconSource -> FASymbol/FAFont/FluentIcon equivalents). Fix MainWindow partial classes to inherit Window and correct missing variables/fields/usings. Add migration docs/specs/tasks under .trae and include a small TestFluentIcons project for icon testing. * Migrate to Avalonia 12 and Plugin SDK v5 Upgrade project to the Avalonia 12 baseline and Plugin SDK v5: centralize Avalonia packages, remove legacy WebView.Avalonia usage (use NativeWebView/WebView2 EnvironmentRequested), and update Fluent/Material icon/package usages. Bump multiple package/project versions to 5.0.0 and Avalonia 12.0.1, update plugin template and README/docs to SDK v5, and add PLUGIN_SDK_V5_MIGRATION.md. Also fix runtime/behavior bugs: make DataLocationResolver use a fixed bootstrap launcher data path and avoid recursive ResolveDataRoot; add legacy-state handling and extraction in OobeStateService; and update component settings tests to reflect migrated storage (DB/backup) and reset cache for test reloads. Various csproj, tests, and docs updated to reflect the migration and ensure build/test compatibility. * Update icon glyphs and symbol mappings Replace and refine icon sources across settings pages and controls: many FAFontIconSource glyphs were updated to specific Seagull Fluent Icons codepoints, some FASymbolIconSource usages were replaced with FAFontIconSource, and a number of symbol-to-Symbol enum mappings were adjusted (e.g. "Bell" -> AlertOn, "Shield" -> ShieldLock). Also clarified a comment in SettingsWindow and fixed a trailing newline in StudySettingsPage. Changes standardize icon visuals and bridge FluentIcons glyphs into FluentAvalonia icon sources. * fix.修复合并产生的问题。
2026-04-29 12:14:29 +08:00
<PackageReference Include="LanMountainDesktop.PluginSdk" Version="5.0.0" />
2026-04-13 19:54:37 +08:00
</ItemGroup>
<ItemGroup>
<None Update="plugin.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Localization\**\*.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
```
### 关键配置项
| 配置项 | 说明 | 推荐值 |
|-------|------|--------|
| `TargetFramework` | 目标框架 | `net10.0` |
| `LangVersion` | C# 语言版本 | `latest` |
| `Nullable` | 可空引用类型 | `enable` |
### SDK 引用
```xml
Avalonia12 (#7) * ava12升级 * Enable centralized package versioning Add <Project> and <PropertyGroup> with <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally> to Directory.Packages.props to enable centralized package version management across the repository. This allows package versions to be controlled from this single file instead of individual project files. * Migrate codebase to Avalonia 12 APIs Apply Avalonia 12 migration changes: replace SystemDecorations with WindowDecorations and remove ExtendClientAreaChromeHints/ExtendClientAreaTitleBarHeightHint usages; update BindingPlugins removal logic (no-op); switch clipboard usage to ClipboardExtensions.SetTextAsync; update Bitmap.CopyPixels calls to the new signature. Replace TextBox.Watermark with PlaceholderText, convert NumberBox styles to FANumberBox and adjust templates, change Checked/Unchecked handlers to IsCheckedChanged, and adapt FluentIcons usages (SymbolIconSource -> FASymbol/FAFont/FluentIcon equivalents). Fix MainWindow partial classes to inherit Window and correct missing variables/fields/usings. Add migration docs/specs/tasks under .trae and include a small TestFluentIcons project for icon testing. * Migrate to Avalonia 12 and Plugin SDK v5 Upgrade project to the Avalonia 12 baseline and Plugin SDK v5: centralize Avalonia packages, remove legacy WebView.Avalonia usage (use NativeWebView/WebView2 EnvironmentRequested), and update Fluent/Material icon/package usages. Bump multiple package/project versions to 5.0.0 and Avalonia 12.0.1, update plugin template and README/docs to SDK v5, and add PLUGIN_SDK_V5_MIGRATION.md. Also fix runtime/behavior bugs: make DataLocationResolver use a fixed bootstrap launcher data path and avoid recursive ResolveDataRoot; add legacy-state handling and extraction in OobeStateService; and update component settings tests to reflect migrated storage (DB/backup) and reset cache for test reloads. Various csproj, tests, and docs updated to reflect the migration and ensure build/test compatibility. * Update icon glyphs and symbol mappings Replace and refine icon sources across settings pages and controls: many FAFontIconSource glyphs were updated to specific Seagull Fluent Icons codepoints, some FASymbolIconSource usages were replaced with FAFontIconSource, and a number of symbol-to-Symbol enum mappings were adjusted (e.g. "Bell" -> AlertOn, "Shield" -> ShieldLock). Also clarified a comment in SettingsWindow and fixed a trailing newline in StudySettingsPage. Changes standardize icon visuals and bridge FluentIcons glyphs into FluentAvalonia icon sources. * fix.修复合并产生的问题。
2026-04-29 12:14:29 +08:00
<PackageReference Include="LanMountainDesktop.PluginSdk" Version="5.0.0" />
2026-04-13 19:54:37 +08:00
```
⚠️ **版本必须匹配:**
- SDK 版本必须与 `plugin.json` 中的 `apiVersion` 兼容
- 建议使用最新稳定版
### 资源文件配置
确保 `plugin.json` 和本地化文件被正确复制到输出目录:
```xml
<ItemGroup>
<None Update="plugin.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Localization\**\*.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
```
---
## 🚪 Plugin.cs - 入口类
插件的入口点,负责初始化逻辑。
### 基本结构
```csharp
using LanMountainDesktop.PluginSdk;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace MyPlugin;
[PluginEntrance]
public sealed class Plugin : PluginBase
{
public override void Initialize(HostBuilderContext context, IServiceCollection services)
{
// 在这里注册组件、设置页面、服务等
// 示例:注册桌面组件
// services.AddPluginDesktopComponent<MyWidget>(...);
// 示例:注册设置页面
// services.AddPluginSettingsSection(...);
}
}
```
### 关键特性
| 特性/类 | 说明 |
|--------|------|
| `[PluginEntrance]` | 标记插件入口类,必须有且仅有一个 |
| `PluginBase` | 插件基类,提供基础功能和日志访问 |
| `Initialize` | 初始化方法,宿主启动时调用 |
### Initialize 方法参数
```csharp
public override void Initialize(HostBuilderContext context, IServiceCollection services)
```
| 参数 | 类型 | 说明 |
|-----|------|------|
| `context` | `HostBuilderContext` | 宿主构建上下文,可访问配置 |
| `services` | `IServiceCollection` | 依赖注入服务集合,用于注册组件和服务 |
---
## 🌍 Localization - 本地化文件夹
存放多语言资源文件,支持插件的国际化。
### 文件夹结构
```
Localization/
├── zh-CN.json # 简体中文
├── zh-TW.json # 繁体中文
├── en-US.json # 英文(美国)
├── ja-JP.json # 日文
└── ko-KR.json # 韩文
```
### 资源文件格式
```json
{
"PluginName": "我的插件",
"Settings": {
"Title": "设置",
"RefreshInterval": "刷新间隔"
},
"Messages": {
"Loading": "加载中...",
"Error": "出错了:{0}"
}
}
```
### 在代码中使用
```csharp
// 获取本地化字符串
var localizer = serviceProvider.GetRequiredService<IStringLocalizer<MyPlugin>>();
var pluginName = localizer["PluginName"];
var message = localizer["Messages.Error", errorDetails];
```
### 支持的语言代码
| 语言 | 代码 |
|-----|------|
| 简体中文 | `zh-CN` |
| 繁体中文 | `zh-TW` |
| 英文 | `en-US` |
| 日文 | `ja-JP` |
| 韩文 | `ko-KR` |
---
## 📦 构建输出结构
运行 `dotnet build` 后,生成的输出结构:
```
bin/Debug/net10.0/
├── MyPlugin.dll # 插件程序集
├── MyPlugin.pdb # 调试符号
├── plugin.json # 插件清单(复制)
├── Localization/ # 本地化文件夹(复制)
│ └── zh-CN.json
├── MyPlugin.laapp # 插件包(由 SDK 自动生成)
└── ...(依赖项 DLL
```
### .laapp 包结构
`.laapp` 文件本质是一个 ZIP 压缩包,包含:
```
MyPlugin.laapp
├── plugin.json # 清单文件
├── MyPlugin.dll # 主程序集
├── Localization/ # 本地化资源
└── ...(其他依赖 DLL
```
---
## 🔗 与其他 .NET 项目的区别
| 特性 | 普通 .NET 应用 | 阑山桌面插件 |
|-----|---------------|-------------|
| 入口点 | `Program.cs``Main` | `Plugin.cs``Initialize` |
| 运行方式 | 独立运行 | 由宿主加载运行 |
| 依赖注入 | 自行配置 | 使用宿主提供的 `IServiceCollection` |
| 输出格式 | `.exe``.dll` | `.laapp` 包 |
| 资源访问 | 直接访问 | 通过 SDK API 访问宿主资源 |
| 热重载 | 支持 | 不支持(需重启宿主) |
---
## 🎯 最佳实践
### 项目组织建议
```
MyPlugin/
├── plugin.json
├── MyPlugin.csproj
├── Plugin.cs # 入口类(保持简洁)
├── README.md
├── .gitignore
├── Localization/ # 本地化资源
├── Services/ # 服务类文件夹
│ ├── WeatherService.cs
│ └── DataService.cs
├── Views/ # 视图文件夹
│ ├── WeatherWidget.axaml
│ ├── WeatherWidget.axaml.cs
│ └── SettingsPage.axaml
└── ViewModels/ # 视图模型文件夹
├── WeatherViewModel.cs
└── SettingsViewModel.cs
```
### 文件命名规范
| 类型 | 命名约定 | 示例 |
|-----|---------|------|
| 入口类 | `Plugin` | `Plugin.cs` |
| 组件视图 | `{Name}Widget` | `WeatherWidget.axaml` |
| 设置页面 | `{Name}SettingsPage` | `WeatherSettingsPage.axaml` |
| 服务类 | `{Name}Service` | `WeatherService.cs` |
| 视图模型 | `{Name}ViewModel` | `WeatherViewModel.cs` |
---
## 📚 参考资源
- [Plugin SDK 源码](../../LanMountainDesktop.PluginSdk/)
- [插件模板](../../LanMountainDesktop.PluginTemplate/content/)
- [02-桌面组件系统](../02-核心概念与原理/02-桌面组件系统.md)
- [03-设置系统集成](../02-核心概念与原理/03-设置系统集成.md)
---
## 🎯 下一步
理解了项目结构后,接下来学习:
👉 **[04-调试运行指南](04-调试运行指南.md)** - 掌握调试技巧
或者深入了解核心概念:
👉 **[01-插件生命周期](../02-核心概念与原理/01-插件生命周期.md)** - 理解插件运行机制
---
*最后更新2026年4月*