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 返回给主程序。

输入链接
CanHandle
ResolveDownloadsAsync
AddTask 入队
下载与后处理

外部插件通过 PluginRuntimeService 从已安装插件目录加载。程序集会先被复制到临时 shadow 目录,再使用独立 AssemblyLoadContext 加载,以减少文件锁和依赖冲突。

plugin.json 清单

插件 zip 包内必须能找到 plugin.json。源码中的校验要求至少提供 IdDisplayNameVersion;为了发布完整,建议补全全部字段。

字段: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。