Plugin Basics
About 598 wordsAbout 2 min
2026-08-14
This page covers the plugin loading flow, apiVersion rules, page registration and localization, and how plugins read and write configuration.
Loading Flow
On desktop startup, the host processes plugins in the following order:
- Process uninstall markers: plugin folders carrying a
.uninstallmarker are removed on this startup (the config directory is preserved, see Uninstall & Config Semantics). - Process pending packages:
.srpxpackages indata/cache/plugin-packagesare extracted todata/plugins/<id>; a package with the same id replaces the whole directory for updates. - Discover plugins: scan each
manifest.ymlunderdata/plugins, merging in the external development directories given by--epp. - Validate manifests and resolve the load order: topologically sort by
dependencies; cycles and missing required dependencies mark the plugin as failed. - Load: create a dedicated
PluginLoadContextper plugin, find the single non-abstractPluginBaseimplementation in the entrance assembly, and callInitialize.
Plugin Directories
- Installed plugins:
data/plugins/<id> - Pending packages:
data/cache/plugin-packages - Plugin-private config:
data/config/plugins/<id>
apiVersion & Versions
- The
apiVersioninmanifest.ymldeclares the host API the plugin targets; its major must be at least the host'sPluginApiVersions.Current.Major(currently3). Plugins that don't meet this are rejected. apiVersionfollows the application major version;versionis the plugin's own version, independent ofapiVersion.- The plugin
versiondrives update detection in the market; installation is keyed byid, so a package with the same id is treated as an update.
Page Registration & Localization
Plugins can register settings pages and main pages:
- Page ids follow the
plugin.<id>.*namespace and must be unique at the application registry level. - Register with the Core extensions:
services.AddSettingsPage<T>(title)/services.AddMainPage<T>(title), and annotate the page class with[PageInfo("plugin.<id>.xxx", Icon)]. - Registration happens in the plugin entry's
Initialize, before the host Host is built.
Localization:
- User-visible strings are maintained per page folder as
Resources.resx,Resources.en-US.resx, andResources.ja-JP.resx, with Simplified Chinese, English, and Japanese all present. - Use the
PublicResXFileCodeGeneratorresource designer; register onlyResources.resxandResources.Designer.csin the project file. - Switching the application language requests a restart; after restart the plugin resources load the matching language from
CultureInfo.CurrentUICulture. Plugins should not assume a fixed culture, nor merge page text into the host's shared resource bucket.
Configuration
Plugins inject MainConfigHandler through DI to read/write the main config, or subclass ConfigHandlerBase<T> to manage their own config:
public override void Initialize(HostBuilderContext context, IServiceCollection services)
{
services.AddSingleton<MyPluginConfigHandler>();
}- Collection config changes are not auto-saved; call
Save()after mutating them. - Do not modify the main config's persistence paths directly; plugin-private files belong in
PluginConfigFolder(that is,data/config/plugins/<id>).
Uninstall & Config Semantics
- Uninstall: the settings page writes a
.uninstallmarker; the plugin directory is removed on next startup, and thedata/config/plugins/<id>config directory is preserved. - Enable/disable: the settings switch writes a
.disabledmarker, applied on next startup. - Crash auto-disable: when a global exception's stack belongs to a plugin load context, that plugin is automatically marked
.disabledand skipped on next startup.
Security Boundary
Plugins run inside the host process and are not sandboxed: plugin code has the same process privileges and data access as the host. Market verification (SHA-256 and Ed25519 signatures) guarantees package integrity, but in-process plugins should still be treated as trusted code. Do not grant data or credential access to plugins from untrusted sources.
Contributors
Changelog
4088d-Update navbar links and remove Advanced Settingson
Copyright
Copyright Ownership:SECTL
License under:CC BY-NC-SA 4.0
