尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

PowerToys Run 插件开发规范:从命名、plugin.json 到安装包签名与本地化的完整清单

PowerToys Run 插件开发规范:从命名、plugin.json 到安装包签名与本地化的完整清单 PowerToys Run 插件开发规范从命名、plugin.json 到安装包签名与本地化的完整清单【免费下载链接】PowerToysMicrosoft PowerToys is a collection of utilities that supercharge productivity and customization on Windows项目地址: https://gitcode.com/GitHub_Trending/po/PowerToysMicrosoft PowerToys 的 PowerToys Run启动器采用 C# 插件化架构每个插件都是src/modules/launcher/Plugins下独立的 .NET 项目通过plugin.json声明自身身份由核心加载器动态加载。本文基于仓库中的《New plugin checklist》清单原文整理完整保留清单的每一项要求并结合仓库内真实插件Calculator、ValueGenerator 等的项目文件、清单文件与公共属性逐项说明其背后的工程约定与实现依据帮助你在提交 PR 前确保新插件能顺利通过构建、安装与本地化全流程。清单适用范围插件在仓库中的位置清单第一条即规定插件必须是modules\launcher\Plugins下的一个项目当前仓库对应 src/modules/launcher/Plugins 目录。从该目录的实际内容看现有插件可分成两类命名体系与清单中给出的两种项目名模式一一对应模式项目名规范仓库内实例微软官方插件Microsoft.PowerToys.Run.Plugin.{PluginName}Calculator、TimeDate、Registry、History、OneNote、System、Service、WindowsSettings、WindowsTerminal、PowerToys社区插件Community.PowerToys.Run.Plugin.{PluginName}ValueGenerator、UnitConverter、WebSearch、VSCodeWorkspaces此外还有一批沿用旧命名风格的插件如Microsoft.Plugin.Program、Microsoft.Plugin.Folder、Microsoft.Plugin.WindowWalker等它们是历史遗留结构按清单要求新增插件应使用上面两种新式命名模式。清单还规定插件的目标框架应为net10.0-windows10.0.22621.0。以 ValueGenerator 的 csproj 为例插件工程文件本身并未重复写死 TFM而是通过Import Project$(RepoRoot)src\Common.Dotnet.CsWinRT.props /引入仓库级公共属性可以推断目标框架等基础构建参数由根目录的公共构建属性统一下发各插件只需保证不与之冲突即可。第三方依赖与 DynamicPlugin.props清单中两条强相关的要求是如果插件使用任何第三方依赖项目文件必须导入DynamicPlugin.props第三方依赖必须兼容 .NET 10。仓库中该文件位于 src/modules/launcher/Plugins/DynamicPlugin.props其内容揭示了它的作用机制PropertyGroup EnableDynamicLoadingtrue/EnableDynamicLoading /PropertyGroup ItemDefinitionGroup ProjectReference Private Condition$(OutputType) libraryfalse/Private /ProjectReference /ItemDefinitionGroup从这两个配置可以读出其设计意图EnableDynamicLoadingtrue打开动态加载开关与plugin.json中的DynamicLoading字段配合表示该插件的依赖应独立于核心应用隔离加载避免插件的第三方程序集污染 PowerToys Run 主进程依赖将项目引用ProjectReference的Private置为false意味着编译时引用的程序集不会被复制到插件输出目录——运行时由加载器按清单统一解析这正是隔离加载的前提。不导入该文件的轻量插件如 Calculator则把Wox.Infrastructure、Wox.Plugin等公共库直接静态引用由核心统一提供。plugin.json插件的机器可读身份声明清单要求每个插件的根目录必须包含格式如下原文模板完整保留的plugin.json{ ID: string, // GUID 字符串 ActionKeyword: string, // 直接激活短语 IsGlobal: boolean, Name: string, // 必须唯一且与项目名模式中的 PluginName 相同 Author: string, Version: 1.0.0, // 为未来兼容性预留 Language: csharp, // 目前仅支持 csharp Website: https://aka.ms/powertoys, // 必须是 http:// 或 https:// 开头的绝对 URI ExecuteFileName: string, // 应为 {Type}.PowerToys.Run.Plugin.{PluginName}.dll IcoPathDark: string, // 深色主题图标路径相对插件根目录 IcoPathLight: string, // 浅色主题图标路径相对插件根目录 DynamicLoading: bool // 插件是否应动态加载与核心应用隔离的依赖 }结合仓库内两个真实清单文件可以看到各字段的实际取值形态Calculator 插件plugin.json{ ID: CEA0FDFC6D3B4085823D60DC76F28855, ActionKeyword: , IsGlobal: true, Name: Calculator, Author: cxfksword, Version: 1.0.0, Language: csharp, Website: https://aka.ms/PowerToys, ExecuteFileName: Microsoft.PowerToys.Run.Plugin.Calculator.dll, IcoPathDark: Images\\calculator.dark.png, IcoPathLight: Images\\calculator.light.png }ValueGenerator 社区插件plugin.json{ ID: a26b1bb4dbd911edafa10242ac120002, ActionKeyword: #, isGlobal: false, Name: ValueGenerator, Description: A plugin to calculate hashes and generate values, Author: IHorvalds, Version: 1.0.0, Language: csharp, Website: https://aka.ms/PowerToys, IcoPathDark: Images\\ValueGenerator.dark.png, IcoPathLight: Images\\ValueGenerator.light.png, ExecuteFileName: Community.PowerToys.Run.Plugin.ValueGenerator.dll }对照两个实例可以归纳出清单隐含的实操细节ID是 GUID 字符串可含连字符或不带实例中两种写法均存在是插件在系统中的唯一身份后续Main.PluginID必须与它一致ActionKeyword是直接激活短语在 PowerToys Run 输入框中键入该关键词即可直接命中该插件如直达计算器#直达 ValueGeneratorIsGlobal决定插件结果是否参与全局搜索匹配Calculator 为trueValueGenerator 为false。从 JSON 解析角度看两个实例分别使用了大小写不一致的键名IsGlobal/isGlobal说明宿主解析对键名大小写不敏感但新插件建议统一采用清单模板中的IsGlobal写法Name必须与项目名模式里的{PluginName}一致且全局唯一ExecuteFileName即插件编译产物 DLL 的文件名须等于{Type}.PowerToys.Run.Plugin.{PluginName}.dll与项目名保持一致IcoPathDark/IcoPathLight相对插件根目录通常放在Images子目录并遵循xxx.dark.png/xxx.light.png命名可从各插件的 Images 目录结构印证DynamicLoading为较新引入的字段旧插件如 Calculator的清单中尚未出现新插件应显式声明并与是否导入DynamicPlugin.props保持一致部分插件还会额外携带Description等扩展字段如 ValueGenerator不影响清单要求的基础字段校验。plugin.json需要随构建输出到插件目录。以 ValueGenerator 的 csproj 为例其中通过如下方式保证ItemGroup None Includeplugin.json CopyToOutputDirectoryPreserveNewest/CopyToOutputDirectory /None /ItemGroup同时其OutputPath指向$(RepoRoot)$(Platform)\$(Configuration)\RunPlugins\ValueGenerator\说明各插件产物统一汇集到RunPlugins下按插件名分目录为安装器收集资源做好准备。Main 类与 PluginID 的一致性清单要求插件的Main类必须包含一个 public static string 的PluginID属性且取值必须与plugin.json中的ID相同。清单给出的最小示例为public static string PluginID xxxxxxx; // xxxxxxx 代表插件 ID 本身仓库实例可直接印证这一约定ValueGenerator/Main.cs 中声明public static string PluginID a26b1bb4dbd911edafa10242ac120002;与其 plugin.json 的ID完全一致TimeDate 插件的Main.cs中PluginID 5D69806A5A474115821C3E4C56B9C793同样与其清单文件对应。这一双重身份声明的意义在于宿主加载 DLL 后无需依赖外部 JSON 即可通过反射取得插件身份PluginID与plugin.json的 ID 不一致属于清单明确拦截的缺陷。此外清单还有一条命名纪律插件项目内部的实体不要使用插件名或 PowerToys 作前缀。从实例可印证这一点——ValueGenerator 的内部类型直接叫Main、InputParser、GeneratorData等没有ValueGeneratorMain、PowerToysXxx之类的前缀命名空间已经承担了隔离职责。单元测试要求MSTest清单明确插件必须包含单元测试使用 MSTest 框架。仓库内已按此组织好对应结构——绝大多数插件都有平行的*.UnitTest(s)工程例如Community.PowerToys.Run.Plugin.ValueGenerator.UnitTestsMicrosoft.PowerToys.Run.Plugin.TimeDate.UnitTestsMicrosoft.PowerToys.Run.Plugin.Calculator.UnitTestMicrosoft.PowerToys.Run.Plugin.System.UnitTests新增插件时应比照这些既有测试工程为输入解析如InputParser与结果生成逻辑编写可独立运行的 MSTest 用例再提交 PR。本地构建验证与安装包集成清单在 PR 前的两条硬性要求用本地构建验证插件构建安装器 → 安装 → 确认插件按预期工作插件的输出代码与资源必须纳入安装器定义。清单原文指向 installer/PowerToysSetup/Product.wxs在当前仓库中安装包产品定义实际位于 installer/PowerToysSetupVNext/Product.wxsWiX 产品定义与Common.wxi、各模块.wxs同目录新插件需要把自己的 DLL 与资源plugin.json、Images图标等加入其中否则安装后插件目录不完整。仓库还提供 installer/PowerToysSetupVNext/generateAllFileComponents.ps1 等脚本用于按文件树生成组件条目可作为补齐安装项时的参考入口。签名流水线纳入清单最后一项所有插件二进制必须纳入签名构建。清单指向仓库.pipelines目录下的签名流水线配置文档原文引用.pipelines/pipeline.user.windows.yml。从 仓库 .pipelines 目录 中可见的ESRPSigning_core.json、ESRPSigning_cmdpal_msix_content.json等签名配置及versionAndSignCheck.ps1、tsa.json等脚本可以推断CI 会对纳入清单的每个产物执行 ESRP 签名校验新插件的 DLL 若未登记流水线将拒绝未签名产物。本地化Localization流程清单末尾指出部分本地化步骤只能在本地化团队提供本地化资源之后进行。对新增插件的 PR规范要求在 PR 中引用一个新 issue用于跟踪为新插件完整启用本地化的后续工作把资源文件夹加入安装器的资源区清单原文以带行号的 GitHub 锚点指向Product.wxs的资源段落对应当前仓库 installer/PowerToysSetupVNext/Product.wxs 中资源目录的收录段与资源文件段将本地化资源文件各语言的 resx/resw添加到对应小节插件的可执行文件DLL构建后必须携带正确的版本信息——该版本信息会显示在设置页中。仓库内插件普遍采用Properties/Resources.resxResources.Designer.cs的强类型资源组织方式如 ValueGenerator、TimeDate 均如此新插件遵循同一模式即可让本地化团队以既定流程注入翻译资源。提交前自检清单汇总检查项依据 / 验证位置项目位于modules\launcher\Plugins下src/modules/launcher/Plugins 目录结构项目名符合Microsoft.PowerToys.Run.Plugin.{PluginName}或Community.PowerToys.Run.Plugin.{PluginName}清单第 4–5 条目标框架为net10.0-windows10.0.22621.0清单第 6 条含第三方依赖时导入DynamicPlugin.props且依赖兼容 .NET 10DynamicPlugin.props根目录含格式正确的plugin.jsonExecuteFileName、双主题图标路径有效对照 Calculator、ValueGenerator 实例Main.PluginID为 public static string且与plugin.json的ID相同ValueGenerator/Main.cs插件内实体不带插件名 / PowerToys 前缀清单第 28 行条目使用 MSTest 编写单元测试工程各*.UnitTests平级工程产物与资源已纳入 Product.wxs清单第 36 行条目本地构建安装器 → 安装 → 实测插件清单第 37 行条目全部二进制登记进签名流水线.pipelines 签名配置PR 引用本地化跟踪 issue资源目录与本地化文件按Product.wxs资源段添加DLL 版本信息正确设置页展示清单末尾三条遵循这份清单你的新插件就能与仓库现有二十余个插件保持同一套工程约定命名可预期、依赖可隔离、身份可校验、产物可安装、二进制可签名、文案可本地化——这正是 PowerToys Run 插件生态能够持续吸收社区贡献的工程基础。【免费下载链接】PowerToysMicrosoft PowerToys is a collection of utilities that supercharge productivity and customization on Windows项目地址: https://gitcode.com/GitHub_Trending/po/PowerToys创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表