6.1 KiB
Troubleshooting
First stop: the log
Everything is in %APPDATA%\LiveWall\logs\livewall-YYYYMMDD.log. Plugin lines are prefixed with the
plugin id:
[com.example.clock] Clock plugin starting (plugin API 1.0, host 1.8.0)
[plugins] loaded com.example.clock v1.0.0 (sha256 3f8c…, verified)
Also useful:
- Plugins ▸ Plugin log — in-app summary: every plugin, its state, hash, permissions, overlays, pages, commands, filters, renderers.
- Advanced ▸ Diagnostics — the same report inside the full diagnostics dump, plus the engine state.
- Advanced ▸ Open log folder.
The plugin does not appear in the list
| Symptom | Cause | Fix |
|---|---|---|
| Folder listed but named after the folder | plugin.json missing or unparsable |
Fix the JSON; the row says Invalid manifest: … |
| Nothing at all | Wrong folder | Must be %APPDATA%\LiveWall\plugins\<something>\plugin.json, not plugins\plugin.json |
| Nothing at all | Plugin system off | Plugins ▸ Enable the plugin system (warning required) |
Appears, greyed state Incompatible |
apiVersion major mismatch or minHostVersion too new |
Update the plugin, or lower minHostVersion |
Appears, Rejected |
checksum in the manifest does not match the DLL |
Rebuild, or clear checksum |
Appears, Failed |
Assembly/type problem, or Initialize threw |
Read the state message; fix the type name or the exception |
Appears, NotApproved |
Loaded and ready, waiting for the user | Press Enable and accept the warning |
Enable does nothing / warning reappears every time
- "allow unverified plugins" is off and the plugin is unverified → turn that option on (in the Plugin system card) or use a build whose hash you approved before.
- The hash changes on every build (normal). Approving a build approves that binary; rebuild and you are asked again. During development, leave Allow unverified on and keep an eye on the log rather than re-approving each time.
- A Forget trust click clears the stored hash — that is what it does.
"Could not load file or assembly … LiveWall.Sdk"
The plugin was built with an incompatible SDK, or it shipped its own LiveWall.Sdk.dll. Delete the
copy from the plugin folder and reference the SDK with <Private>false</Private>.
"Cannot cast … to ILiveWallPlugin"
Same cause: a second copy of the contract assembly. The plugin's ILiveWallPlugin came from a
different assembly identity than the host's.
Overlay does not show up
- Is the plugin Active and does the log mention
overlay registered? - Is the desktop icon window alive? LiveWall creates the overlay host window even with desktop icons disabled, but a third-party shell replacement (StartAllBack, ExplorerPatcher) can break WorkerW — press Re-attach on the Display tab.
- Did you return a
FrameworkElementwith a size? AStackPanelwith no children is invisible. - Is it behind the icons by design? The overlay sits above the wallpaper and below the icons; text in the top-right corner is a safe place to test.
- Did you call
OnVisibilityChangedcorrectly? LiveWall calls it withfalsewhen overlays are hidden (tray Hide overlay), so a timer you stopped there must be restarted ontrue.
Clicks on my overlay do nothing
Expected. The overlay layer is IsHitTestVisible = false: clicks must reach the desktop icons. If you
need interaction, that is a renderer feature (renderers live in the wallpaper window and can be made
interactive with InteractiveMode), not an overlay feature.
Settings page is blank
CreateView threw. The exception is shown in the page and logged. The usual culprit is referencing
LiveWall.Themes resources by key that does not exist — the safe keys are BgWindow, BgCard,
BgField, BgHover, BorderBrushSoft, TextBrush, TextDim, AccentBrush, AccentSoft,
GreenBrush, DangerBrush, and the styles Card, Hint, SectionTitle, PageTitle,
AccentButton, GhostButton, TinyButton, Label, Mono.
Hotkey does nothing
- Another app (or LiveWall itself) already owns the combination — the log says so.
- Gesture syntax: modifiers first (
Ctrl+Alt+K), one key.Ctrl+Shift+3is not valid,Ctrl+Shift+D3is. - The
Hotkeyspermission must be declared.
Filter breaks wallpaper changes
Filters run before the engine applies a request, including requests from playlists and other
plugins. A filter that always returns a fixed request effectively pins the wallpaper (that is the point
of the sample's Pin wallpaper option). Exceptions inside Apply disable your filter for that pass
and are logged; they do not disable the plugin.
Renderer never gets used
CanRendermust returntruefor the request the engine actually sees — after filters. Log what you receive.- Another plugin with a higher
Priorityclaimed it first. Priorities are per plugin; the firsttruewins. - The
Rendererpermission must be declared, otherwiseAddRendereris refused. - After a source change LiveWall calls
Createonce andLoadper source. IfLoadthrows, the message appears in the status line and the plugin is not retried for that source.
Unloading
LiveWall unloads a plugin when it is disabled, rescanned, or when the app exits. The collectible load context only actually releases the assembly if nothing keeps a reference alive:
- unsubscribe every
IDisposableyou got fromEvents.SubscribeinShutdown; - stop and unhook
DispatcherTimers,System.Timers.Timers,FileSystemWatchers; - do not keep static references in the host's types to your objects (a static in a host-owned class is fine only if it lives in your assembly);
- do not leave
Tasks running: observecontext.ShutdownToken.
If a plugin stays "loaded" after Disable, the log says unload deferred — restart LiveWall to finish
the job. This is a leak in the plugin, not in LiveWall.
Reporting a bug
Include: LiveWall version, plugin id + version + hash (from the warning dialog or Plugin log), the relevant log excerpt, and the exact steps. If the app crashed, the last lines of the log before the crash are usually enough to identify the plugin.