Documentation
FlashDown 插件开发与技术参数
本页根据源码中的 Contracts.cs、PluginRuntimeService 和 PluginPackageService 整理,覆盖运行环境、插件接口、清单字段、包结构、加载规则和 AI 插件开发提示词。
技术参数
FlashDown 当前主要面向 Windows 桌面环境,主程序使用 .NET 8 与 WinUI 3,插件项目建议使用 net8.0。
| 参数 | 值 |
|---|---|
| 应用框架 | .NET 8 + WinUI 3 |
| 目标系统 | Windows 10 1809 或更高版本 |
| 插件目标框架 | net8.0 |
| 插件程序集匹配 | *.Plugin.dll |
| 插件包清单 | plugin.json |
| 用户数据目录 | %LocalAppData%\FlashDown\ |
架构说明
主程序负责任务队列、下载引擎、状态存储、插件安装、插件加载和下载任务入队。插件负责识别输入、授权状态、解析下载项,并把结果转换为 PluginResolvedDownload 返回给主程序。
外部插件通过 PluginRuntimeService 从已安装插件目录加载。程序集会先被复制到临时 shadow 目录,再使用独立 AssemblyLoadContext 加载,以减少文件锁和依赖冲突。
plugin.json 清单
插件 zip 包内必须能找到 plugin.json。源码中的校验要求至少提供 Id、DisplayName、Version;为了发布完整,建议补全全部字段。
字段:Id, DisplayName, Summary, Version, Author, HandlerId, EntryKey, ConfigWindowTitle, MinimumAppVersion, Enabled
{
"Id": "flashdown.example",
"DisplayName": "Example Downloader",
"Summary": "Resolve example.com links and enqueue direct downloads.",
"Version": "1.0.0",
"Author": "Your Name",
"HandlerId": "example.download",
"EntryKey": "example.download",
"ConfigWindowTitle": "Example Plugin",
"MinimumAppVersion": "1.2.5",
"Enabled": true
}
HandlerId 注意事项:外部插件不要使用内置 HandlerId:baidu.pan、web.media、short.video、netease.music。通用外部插件会跳过这些内置 HandlerId。
接口规范
插件程序集需要引用 FlashDown.Plugin.Abstractions。下载解析插件至少实现 IShareDownloadPlugin,它继承自 IFlashDownPlugin。
public interface IFlashDownPlugin
{
string PluginId { get; }
string HandlerId { get; }
string DisplayName { get; }
}
public interface IShareDownloadPlugin : IFlashDownPlugin
{
bool CanHandle(string? input);
Task<PluginAuthSession> BeginAuthorizationAsync(string settingsJson, CancellationToken cancellationToken = default);
Task<PluginAuthStatus> CompleteAuthorizationAsync(string settingsJson, string deviceCode, CancellationToken cancellationToken = default);
Task<PluginProfileSnapshot> RefreshProfileAsync(string settingsJson, CancellationToken cancellationToken = default);
string? TryExtractPassword(string? raw);
Task<IReadOnlyList<PluginResolvedDownload>> ResolveDownloadsAsync(
string settingsJson,
string shareText,
string? extractionCode,
CancellationToken cancellationToken = default);
}
如果插件需要工具栏搜索,可实现 IToolbarSearchPlugin;如果需要配置页字段,可实现 IConfigurablePlugin,返回默认设置 JSON、规范化设置 JSON 和字段描述。
PluginResolvedDownload 输出
ResolveDownloadsAsync 返回一个或多个下载项。常用字段包括 Url、FileName、Size、SharePath、ResolvedUrl、RequestCookieHeader、RequestReferer、RequestUserAgent、AdditionalHeaders。
| 字段 | 用途 |
|---|---|
| Url | 主程序实际创建任务时使用的下载地址。 |
| FileName / Size | 展示文件名与大小;大小未知可填 0。 |
| RequestCookieHeader / RequestReferer / RequestUserAgent | 平台下载需要的请求头。 |
| ProxyKind / ProxySourceUrl | 需要代理下载或外部工具时使用,例如 ytdlp、ffmpeg。 |
| PostProcessKind / PostProcessGroupId | 用于音视频合并等后处理流程。 |
| AdditionalHeaders | 额外 HTTP 头,适合平台特定签名或鉴权。 |
打包与加载
插件包是 zip 文件。主程序安装插件时会解压包,查找 plugin.json,并把包含清单的目录复制到用户插件目录。已安装插件默认位于 %LocalAppData%\FlashDown\plugins\,插件包缓存位于 %LocalAppData%\FlashDown\plugin-packages\。
flashdown.example-1.0.0.zip ├─ plugin.json └─ bin/ ├─ FlashDown.Example.Plugin.dll ├─ FlashDown.Example.Plugin.deps.json ├─ FlashDown.Plugin.Abstractions.dll └─ optional-tool.exe
主程序会枚举插件安装目录中的 *.Plugin.dll。如果没有已安装插件,开发环境下还会扫描源码树中 plugins/*/bin/Release/net8.0 和 plugins/*/bin/Debug/net8.0 的输出,方便本地调试。
给 AI 编程工具的标准提示词
复制下面这段提示词,替换目标平台和解析规则后,可交给 AI 编程工具生成插件骨架。
你是资深 .NET 8 插件工程师。请为 FlashDown 开发一个新的外部下载解析插件。插件目标框架为 net8.0,引用 FlashDown.Plugin.Abstractions,实现 IShareDownloadPlugin,必要时实现 IConfigurablePlugin 或 IToolbarSearchPlugin。请避免使用内置 HandlerId:baidu.pan、web.media、short.video、netease.music。输出内容包括:1. 插件项目 csproj;2. plugin.json,字段包含 Id、DisplayName、Summary、Version、Author、HandlerId、EntryKey、ConfigWindowTitle、MinimumAppVersion、Enabled;3. 一个 public sealed 插件类,提供 PluginId、HandlerId、DisplayName、CanHandle、BeginAuthorizationAsync、CompleteAuthorizationAsync、RefreshProfileAsync、TryExtractPassword、ResolveDownloadsAsync;4. ResolveDownloadsAsync 返回 PluginResolvedDownload 列表,填充 Url、FileName、Size、SharePath、ResolvedUrl、RequestCookieHeader、RequestReferer、RequestUserAgent、ProxyKind、ProxyToken、ProxySourceUrl、ProxyAccessToken、ProxyFsId、RemoteCleanupBatchId、RemoteCleanupRootPath,按需填 AdditionalHeaders;5. 打包为 zip,zip 内能找到 plugin.json 和 *.Plugin.dll。请给出完整代码、目录结构和打包命令。
FAQ
插件为什么没有被加载?检查 zip 内是否有 plugin.json、是否存在 *.Plugin.dll、插件类是否 public 且非 abstract、是否实现 IFlashDownPlugin。
为什么 CanHandle 命中但没有入队?检查 HandlerId 是否和内置插件冲突、插件是否启用、ResolveDownloadsAsync 是否返回空列表。
平台需要登录怎么办?使用 BeginAuthorizationAsync、CompleteAuthorizationAsync、RefreshProfileAsync 管理授权状态,并把登录态写入 settingsJson。