CYLDConverter 插件开发手册

🛠️ 开发者版本专用 — 基于 CYLDConverterDev,跳过签名验证,支持热重载 [菜单3],快速迭代。

📖 开发指南目录

  1. 环境要求
  2. 项目配置 (.csproj)
  3. 核心接口 IConverterPlugin
  4. 共享库与依赖规则 ⚠️
  5. 资源搜索 FindResourceFile
  6. 进度报告接口
  7. 完整示例插件
  8. 部署目录结构
  9. 热重载流程
  10. 调试与排错
  11. 迁移至正式版
  12. 快速模板

1. 开发环境要求

组件要求
运行时.NET 8.0 (SDK or Runtime)
目标框架net8.0
IDEVS2022 / Rider / VS Code + C#
项目类型Class Library
程序集名称必须为 Main

2. .csproj 关键配置

⚠️ AssemblyName 必须等于 Main,否则主程序找不到 Main.dll,插件被跳过。
YourPlugin.csprojXML
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <AssemblyName>Main</AssemblyName>          <!-- ★ 固定 ★ -->
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="ConverterPlugins">
      <HintPath>..\CYLDConverterDev\ConverterPlugins.dll</HintPath>
      <Private>false</Private>               <!-- 禁止复制到输出目录 -->
    </Reference>
  </ItemGroup>
</Project>

3. 必需接口:IConverterPlugin

插件主类必须实现 IConverterPlugin,并提供以下成员:

IConverterPlugin 核心定义
public interface IConverterPlugin
{
    string PluginName { get; }                     // 唯一名称
    string PluginInfo { get; }
    string Author { get; }
    string Version { get; }
    string DetailedDescription { get; }
    string CreatedTime { get; }
    string[] SupportedInputExtensions { get; }     // 如 new[] { ".litematic" }
    string SupportedOutputExtension { get; }       // 如 ".schem"
    
    bool Convert(object inputData, string outputPath, 
                 string pluginDirectory, object? options);
}

📌 可选接口 IPluginOptionsProvider:用于动态询问用户参数,返回 List<PluginOption>,主程序自动收集并传入 options 字典。

IPluginOptionsProvider 示例

选项定义
public List<PluginOption>? GetOptions() => new()
{
    new PluginOption { Key = "scale", DisplayName = "缩放比例", ValueType = "float", DefaultValue = "1.0" }
};

4. ⚠️ 共享库规则 (致命错误提醒)

严禁将 ConverterPlugins.dllNewtonsoft.Json.dll 放入插件目录!
主程序已经提供这些程序集。若插件目录出现这两个文件,将导致类型冲突 ("IConverterPlugin exists in both") 且插件无法加载。 在 .csproj 中引用时务必添加 <Private>false</Private>ExcludeAssets="runtime"

5. 推荐资源文件搜索模式 (FindResourceFile)

插件可能需要共享映射表或配置文件。为避免路径硬编码,请实现以下辅助函数(按优先级搜索插件目录 → out子目录 → Plugins根目录):

FindResourceFile 标准实现
private static string? FindResourceFile(string pluginDir, string fileName)
{
    string path = Path.Combine(pluginDir, fileName);
    if (File.Exists(path)) return path;
    path = Path.Combine(pluginDir, "out", fileName);
    if (File.Exists(path)) return path;
    string? parent = Path.GetDirectoryName(pluginDir);
    if (parent != null)
    {
        path = Path.Combine(parent, fileName);
        if (File.Exists(path)) return path;
    }
    return null;
}

6. 进度报告 (Action 回调)

主程序通过 options 参数传入进度回调,插件可在转换过程中调用 reportProgress?.Invoke(percent) 显示进度条。

接收进度回调
public bool Convert(object inputData, string outputPath, string pluginDirectory, object? options)
{
    Action<int>? progress = null;
    if (options is Action<int> direct) progress = direct;
    else if (options is Dictionary<string,object> dict && dict.TryGetValue("__progress__", out var cb) && cb is Action<int> act)
        progress = act;
    progress?.Invoke(0);
    // ... 业务逻辑
    progress?.Invoke(100);
    return true;
}

7. 完整插件示例 (行号添加器)

LineNumberPlugin.csC#
using System.Text;
using ConverterPlugins;

public class LineNumberConverter : IConverterPlugin, IPluginOptionsProvider
{
    public string PluginName => "行号添加器";
    public string PluginInfo => "为文本每行加行号";
    public string Author => "示例";
    public string Version => "1.0";
    public string DetailedDescription => "支持自定义分隔符和起始行号";
    public string[] SupportedInputExtensions => new[] { ".txt", ".log" };
    public string SupportedOutputExtension => ".txt";
    public string CreatedTime => "2026";

    public List<PluginOption>? GetOptions() => new()
    {
        new() { Key = "separator", DisplayName = "分隔符", ValueType = "string", DefaultValue = ": " },
        new() { Key = "startLine", DisplayName = "起始行号", ValueType = "int", DefaultValue = "1" }
    };

    public bool Convert(object inputData, string outputPath, string pluginDirectory, object? options)
    {
        if (inputData is not byte[] bytes) return false;
        var opts = options as Dictionary<string, object> ?? new();
        string sep = opts.GetValueOrDefault("separator") as string ?? ": ";
        int start = opts.GetValueOrDefault("startLine") is int s ? s : 1;
        
        string text = Encoding.UTF8.GetString(bytes);
        var lines = text.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);
        var sb = new StringBuilder();
        for (int i = 0; i < lines.Length; i++)
            sb.Append(start + i).Append(sep).AppendLine(lines[i]);
        File.WriteAllText(outputPath, sb.ToString(), Encoding.UTF8);
        return true;
    }
}

8. 插件部署与目录规范

标准目录树
CYLDConverterDev/
├── CYLDConverterDev.exe
├── ConverterPlugins.dll        (主程序提供,切勿复制到插件文件夹)
├── Plugins/
│   ├── MyPlugin/               (任意插件名)
│   │   └── Main.dll            ★ 必须 Main.dll
│   ├── LitematicConverter/
│   │   └── Main.dll
│   └── shared_mappings.json    (共享资源,可由 FindResourceFile 定位)
└── Logs/
💡 开发版本不要求 .sig 签名文件,正式版本需要额外签名。

9. 热重载开发流程 (开发版专属)

1编译插件:dotnet build -c Release
2bin/Release/net8.0/Main.dll 覆盖到 Plugins/你的插件/
3在 CYLDConverterDev 控制台菜单输入 [3] 重新加载插件,无需重启程序!
建议编写 PowerShell 部署脚本一键完成编译+复制。

10. 常见错误与排查

现象原因解决
跳过: XXX (缺少 Main.dll)程序集输出不是 Main.dll修改 .csproj 添加 <AssemblyName>Main</AssemblyName>
类型冲突 / 接口不存在插件目录包含了 ConverterPlugins.dll删除多余dll,引用的HintPath设置Private=false
重复插件名称,跳过两个插件的 PluginName 相同确保每个插件唯一名称
依赖库 FileNotFoundException第三方dll未放入插件目录复制依赖到插件子目录
资源文件找不到未使用 FindResourceFile采用第5节的搜索逻辑

日志查看目录:Logs/CYLDConverterDev_日期.log,开发版日志级别为 DEBUG。

11. 迁移到正式版签名流程

开发版充分测试插件。
Release 编译得到 Main.dll。
将 Main.dll 提交给管理员获取签名文件 Main.dll.sig (XOR 加密)。
部署到正式版 Plugins/插件名/ 目录,必须包含 Main.dll + Main.dll.sig + 依赖。
正式版没有有效的 .sig 文件插件无法加载!

12. 插件模板 (开箱即用)

PluginTemplate.csC#
using ConverterPlugins;
namespace MyNamespace;

public class MyConverter : IConverterPlugin
{
    public string PluginName => "示例转换器";
    public string PluginInfo => "描述信息";
    public string Author => "YourName";
    public string Version => "1.0";
    public string DetailedDescription => "完整功能描述";
    public string CreatedTime => DateTime.Now.ToString("yyyy-MM-dd");
    public string[] SupportedInputExtensions => new[] { ".dat" };
    public string SupportedOutputExtension => ".txt";
    
    public bool Convert(object inputData, string outputPath, string pluginDirectory, object? options)
    {
        if (inputData is not byte[] bytes) return false;
        File.WriteAllBytes(outputPath, bytes);  // 示例逻辑
        return true;
    }
}
🔥 自动化部署脚本 (PowerShell) — 保存为 deploy.ps1 以提升效率:
$plugin="MyPlugin"; $dest="CYLDConverterDev/Plugins/$plugin"
dotnet build -c Release; Copy-Item "bin/Release/net8.0/Main.dll" "$dest/Main.dll" -Force
Write-Host "部署完成,按主程序 [3] 热重载" -Foreground Green
返回顶部  |  CYLDConverter 插件开发手册 · 基于 v1.4 开发版