5.7 KiB
LiveWall plugin SDK
LiveWall 1.8.0 and later can be extended by plugins: .NET 8 assemblies that LiveWall loads at start-up and hands a context object. A plugin can add wallpaper renderers, draw on the desktop, add settings pages, add commands and tray entries, register hotkeys, rewrite wallpaper requests, and read the same events the app itself uses.
Plugins are third-party code. They run inside LiveWall's process with your rights. LiveWall does not review, sign or sandbox them, and unverified plugins may cause harm to your computer. The user is shown a warning listing the plugin's exact file hash and every permission it declared before it is allowed to run — see security.md.
Contents
| Document | What it covers |
|---|---|
| getting-started.md | From an empty folder to a running plugin in ten minutes |
| api-reference.md | Every interface, member and enum in LiveWall.Sdk |
| extension-points.md | Overlays, renderers, filters, pages, commands, hotkeys — with the caveats |
| events.md | The event catalogue, threading rules and lifetime |
| security.md | Permissions, trust, hashes, the warning dialog, threat model |
| packaging.md | Folder layout, versioning, checksums, distribution, updates |
| troubleshooting.md | "My plugin does not load", reading the log, unload rules |
| examples.md | Copy-paste recipes for the common shapes |
The SDK itself is LiveWall.Sdk.dll — a small contract assembly. Plugins reference it and nothing
else; LiveWall.exe is deliberately not a dependency.
What a plugin can change
| Extension point | Interface | Typical use |
|---|---|---|
| Desktop overlay | IWallpaperOverlay |
Clock, now-playing badge, visualiser, watermark, fps counter |
| Wallpaper renderer | IWallpaperRendererPlugin + IWallpaperRenderer |
Shaders, emulators, animated 3D scenes, a custom video pipeline |
| Wallpaper filter | IWallpaperFilter |
Resolve short links, pick a random source, block changes, add metadata |
| Settings page | IPluginSettingsPage |
Your own configuration UI inside LiveWall |
| Command | PluginCommand |
"Next quote", "Toggle rain", anything the user can trigger |
| Tray entry | PluginCommand + TrayMenu permission |
Same commands, reachable with two clicks |
| Hotkey | PluginHotkey |
Global shortcut for a plugin action |
| Events | IPluginEvents |
React to wallpaper/playback/session changes |
| Host actions | IHostActions |
Set the wallpaper, play/pause, notify, open settings |
| Storage | IPluginStorage |
Persist your own JSON state, own folders |
Everything is registered through IPluginContext.Extensions inside Initialize. There is no
"unregister everything" step: LiveWall drops all of a plugin's registrations when it unloads it.
How loading works (short version)
%APPDATA%\LiveWall\plugins\
└── com.example.clock\ ← one folder per plugin, any name
├── plugin.json ← identity + permissions (required)
├── ClockOverlayPlugin.dll ← entry assembly
└── (any other files you need)
- LiveWall scans the plugin folder at start-up (and whenever the user presses Rescan).
plugin.jsonis validated: API version, host version, optional checksum.- Plugins the user has not enabled stay on disk, unloaded, listed in Plugins ▸ Installed plugins.
- Enabling runs the warning dialog. Only after the user accepts is the assembly loaded — into a
collectible
AssemblyLoadContext— andILiveWallPlugin.Initialize(context)called. - Any exception in
Initializemarks the plugin Failed and shows the message. The app keeps running; a plugin can never take LiveWall down.
Full details in packaging.md and troubleshooting.md.
Quick start
dotnet new classlib -n MyPlugin -f net8.0-windows
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<UseWPF>true</UseWPF>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="path\to\LiveWall.Sdk\LiveWall.Sdk.csproj">
<Private>false</Private>
</ProjectReference>
</ItemGroup>
</Project>
using LiveWall.Sdk;
public sealed class MyPlugin : ILiveWallPlugin
{
public void Initialize(IPluginContext context)
=> context.Host.ShowNotification("MyPlugin", "Hello from the wallpaper!");
public void Shutdown() { }
}
{
"id": "com.example.myplugin",
"name": "My plugin",
"version": "1.0.0",
"author": "you",
"description": "Does one small thing.",
"apiVersion": "1.0",
"entry": "MyPlugin.dll",
"type": "MyPlugin",
"minHostVersion": "1.8.0",
"permissions": ["Commands"]
}
Copy the build output next to the manifest, then use Plugins ▸ Rescan and Enable.
The repository ships a complete, buildable example in samples/ClockOverlayPlugin/ that uses every
extension point — read it next to extension-points.md.
Stability promise
The contracts live in LiveWall.Sdk and are versioned separately from LiveWall's own version:
PluginApi.Version(currently 1.0) is whatplugin.jsonmust declare.- Adding members to an existing interface would break compiled plugins, so new capabilities arrive as new optional interfaces, and the major version only changes if something must be removed.
minHostVersionin the manifest refuses to run on an older LiveWall instead of failing mysteriously.
See packaging.md.