initial commit
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
# 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
|
||||
|
||||
1. Is the plugin **Active** and does the log mention `overlay registered`?
|
||||
2. 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.
|
||||
3. Did you return a `FrameworkElement` with a size? A `StackPanel` with no children is invisible.
|
||||
4. 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.
|
||||
5. Did you call `OnVisibilityChanged` correctly? LiveWall calls it with `false` when overlays are
|
||||
hidden (tray **Hide overlay**), so a timer you stopped there must be restarted on `true`.
|
||||
|
||||
## 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+3` is not valid, `Ctrl+Shift+D3`
|
||||
is.
|
||||
* The `Hotkeys` permission 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
|
||||
|
||||
* `CanRender` must return `true` for the request the engine actually sees — after filters. Log what
|
||||
you receive.
|
||||
* Another plugin with a higher `Priority` claimed it first. Priorities are per plugin; the first `true`
|
||||
wins.
|
||||
* The `Renderer` permission must be declared, otherwise `AddRenderer` is refused.
|
||||
* After a source change LiveWall calls `Create` once and `Load` per source. If `Load` throws, 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 `IDisposable` you got from `Events.Subscribe` in `Shutdown`;
|
||||
* stop and unhook `DispatcherTimer`s, `System.Timers.Timer`s, `FileSystemWatcher`s;
|
||||
* 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 `Task`s running: observe `context.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.
|
||||
Reference in New Issue
Block a user