-
-
Notifications
You must be signed in to change notification settings - Fork 60
Architecture Overview
Sucrose is not a single monolithic application. It is a constellation of small, independent Windows executables that cooperate through three loose coupling mechanisms: short-lived process spawning (Sucrose.Commandog.exe), named-pipe / file-signal / TCP-loopback IPC, and shared on-disk state (settings JSON, readonly constants, and wallpaper library files). The design goal is fault isolation: each concern — UI, rendering, monitoring, crash reporting, updating, uninstall — runs in its own process so that a crash in one does not take down the wallpaper or the tray icon. This page is the developer entry point to the multi-process model: the process roster, why processes are separated, the physical-to-logical folder mapping, who spawns whom, and the conditional-compilation symbols that vary shared code per process.
flowchart TD
User(["User"]) --> Launcher["Sucrose.Launcher.exe<br/>tray entry point"]
Launcher -. owns .-> Tray["System tray icon<br/>+ Discord Rich Presence"]
Launcher -->|spawns| Commandog["Sucrose.Commandog.exe<br/>command dispatcher"]
Commandog --> Portal["Sucrose.Portal.exe"]
Commandog --> Engine["Live engine<br/>Sucrose.Live.*.exe"]
Commandog --> Backgroundog["Sucrose.Backgroundog.exe"]
Commandog --> Reportdog["Sucrose.Reportdog.exe"]
Commandog --> Update["Sucrose.Update.exe"]
Commandog --> Property["Sucrose.Property.exe"]
Commandog --> Watchdog["Sucrose.Watchdog.exe"]
Any["Any process throws"] -->|"Watchdog command (Base64)"| Commandog
Windows(["Windows Apps & Features"]) --> Undo["Sucrose.Undo.exe<br/>uninstaller"]
Engine -. spawns .-> Children["msedgewebview2 /<br/>CefSharp.BrowserSubprocess"]
- The process roster
- Why separate processes
- The three coupling mechanisms
- Physical folders vs. logical layers
- Who spawns whom
- Common per-process startup configuration
- Preprocessor symbols
- See also
Each component runs as its own .exe. Executable names come from src/Library/Sucrose.Memory/Manage/Readonly/App.cs.
| Executable | Folder | Type | Role |
|---|---|---|---|
Sucrose.Launcher.exe |
src/Launcher/Sucrose.Launcher |
WPF (tray, no main window) | Entry point. Owns the system-tray icon + context menu, Discord Rich Presence, and the Launcher signal channel. Routes user actions to Commandog. |
Sucrose.Portal.exe |
src/Portal/Sucrose.Portal |
WPF-UI + MVVM + DI host | The main settings/management window (Library, Store, Settings pages). |
Sucrose.Commandog.exe |
src/Project/Sucrose.Commandog |
Console (hidden) | The command dispatcher / process broker. Parses one encoded command string, starts/kills the right process, then exits. |
Sucrose.Backgroundog.exe |
src/Project/Sucrose.Backgroundog |
Console (hidden) | Background service: audio visualization + system-status data feeds, performance counters, performance/pause rule enforcement. Long-running loop. |
Sucrose.Watchdog.exe |
src/Project/Sucrose.Watchdog |
WPF | Crash handler: decodes a Base64 exception payload, writes a report JSON, optionally shows an error dialog, and kills the faulting process. |
Sucrose.Reportdog.exe |
src/Project/Sucrose.Reportdog |
Console (hidden) | Telemetry / error-report uploader. Long-running loop; runs only when telemetry/exception consent is granted. |
Sucrose.Property.exe |
src/Project/Sucrose.Property |
WPF | Wallpaper "Customize" UI — edits the live wallpaper's user properties. |
Sucrose.Update.exe |
src/Update/Sucrose.Update |
WPF | Auto-update checker / downloader / installer launcher. |
Sucrose.Undo.exe |
src/Project/Sucrose.Undo |
WPF | Uninstall / rollback: terminates Sucrose processes, deletes install + data folders, removes shortcuts and the registry key, then self-deletes. |
| Live engines (8) | src/Live/* |
WPF render hosts | The wallpaper rendering backends (see below). |
The eight live rendering engines and their executables:
| EngineType | Executable | Used for |
|---|---|---|
AuroraLive |
Sucrose.Live.Aurora.exe |
Application wallpapers (embeds an external app on the desktop) |
NebulaLive |
Sucrose.Live.Nebula.exe |
Video |
VexanaLive |
Sucrose.Live.Vexana.exe |
Gif |
XavierLive |
Sucrose.Live.Xavier.exe |
Gif |
WebViewLive |
Sucrose.Live.WebView.exe |
Url / Web / Video / YouTube / Gif (WebView2 backend) |
CefSharpLive |
Sucrose.Live.CefSharp.exe |
Url / Web / Video / YouTube / Gif (CEF backend) |
MpvPlayerLive |
Sucrose.Live.MpvPlayer.exe |
Gif / Video (libmpv backend) |
VlcPlayerLive |
Sucrose.Live.VlcPlayer.exe |
Gif / Video (libVLC via LibVLCSharp.WPF) |
See Engines Overview for the per-type allowed-engine matrix.
-
Fault isolation. A renderer crash, a hung browser child process, or an exception in a service does not crash the tray or the settings window. A central crash handler (
Sucrose.Watchdog.exe) catches failures from every process and a reporter (Sucrose.Reportdog.exe) uploads them. - Independent lifecycles. The wallpaper engine keeps running while the Portal UI is closed; the Launcher tray persists across UI sessions; short-lived workers (Commandog, Watchdog) start, do one job, and exit.
- Backend swapping. Eight interchangeable render engines run as distinct executables, so the user can switch the engine per wallpaper type without affecting the rest of the stack.
-
Privilege & resource separation. Heavy work (audio FFT, perf counters, WMI queries) lives in
Backgroundog; the UI stays light.
-
Process spawning via Commandog. Most cross-process actions are not direct
Process.Startcalls — they are routed throughSucrose.Commandog.exe, which is spawned with a single encoded argument string (✔<Command>✖<value>...), performs the action, and exits. See Commandog Dispatcher and Command Reference. - Live-data IPC channels. Long-running processes exchange live data through three interchangeable transports — Pipe, Signal, and Transmission (TCP loopback, the default) — plus the tray-control "Launcher" channel. See IPC.
-
Shared on-disk state. Settings JSON (
Sucrose.Manager), readonly constants (Sucrose.Memory), and theme/info/properties files in the wallpaper library. See Settings Persistence and Data Locations.
The physical src/ folder names do not match the logical layer names — this is the #1 navigation trap. Services live under src/Project/, and the engine renderers under src/Live/. Always map through this table.
| Physical folder | Contains |
|---|---|
src/Launcher/ |
Sucrose.Launcher |
src/Portal/ |
Sucrose.Portal |
src/Live/ |
The 8 live rendering engines |
src/Project/ |
The Services: Backgroundog, Commandog, Watchdog, Reportdog, Property, Undo
|
src/Library/ |
Shared class libraries (Manager, Memory, Mpv.NET, Pipe, Resources, Signal, Transmission, XamlAnimatedGif) |
src/Shared/ |
Shared Item Projects (.shproj), with engine-specific ones under src/Shared/Engine/
|
src/Update/ |
Sucrose.Update |
src/Bundle/ |
Sucrose.Bundle (installer / packager) |
src/Localizer/ |
Sucrose.Localizer (translation tool) |
src/Sucrose/ |
Build output (generated) |
exp/ |
Experimental ports (Avalonia, Uno, WinUI, Services) — not part of the main solution |
See Repository Layout for the full mapping.
-
The user launches
Sucrose.Launcher.exe. It is the true entry point — a WPF app with no main window that lives in the tray (ShutdownMode = OnExplicitShutdown). -
The Launcher, on start, creates the tray icon, which in turn:
- auto-restores the wallpaper (
Engine.Command(false)→Run.Start()), spawning the live engine through Commandog (✔Live✖<engine.exe>), and first spawningBackgroundog(✔Backgroundog✖<Backgroundog>) whenPerformanceCounteris on; - spawns
Reportdogto flush pending reports; - runs a silent update check (spawns
Update) when auto-update is on.
- auto-restores the wallpaper (
-
Tray actions route through Commandog: Open →
✔Interface✖<Portal>, Customize →✔Property✖<Property>, Reload →✔RestartLive✖Unknown, etc. -
Any process that throws spawns
Watchdogthrough Commandog with a Base64 exception payload;Reportdoglater uploads the report. -
Sucrose.Undo.exeis launched by Windows Apps & Features as the uninstaller and tears the whole installation down.
For the full cold-start sequence and teardown order, see Lifecycle.
Every process runs the same two configuration helpers before anything else:
-
SSDHR.Configure()(Shared.Dependency.Helper.Runtime) — RELEASE-only. Points the process at the bundled private .NET runtime by setting env vars (DOTNET_ROOT,DOTNET_MULTILEVEL_LOOKUP=0,DOTNET_ROLL_FORWARD=LatestMajor) and prepending the runtime folder<parent>/Sucrose.RuntimetoPATH. Debug builds use the machine's installed runtime. -
SSDHG.Configure()(Shared.Dependency.Helper.Graphic) — callsEnsureHighPerformance(exe)so the process is registered for the high-performance GPU on multi-GPU laptops.
Plus: thread culture is set from the Culture setting; WPF apps set ShutdownMode; console apps (Commandog, Backgroundog, Reportdog) set Console.InputEncoding/OutputEncoding = UTF8 so the ✔ / ✖ command delimiters survive. See Lifecycle for details.
Every executable defines a project-specific symbol so that the shared .shproj code can vary behavior with #if. See Preprocessor Symbols for the full reference.
-
App symbols:
LAUNCHER,PORTAL,BACKGROUNDOG,COMMANDOG,WATCHDOG,REPORTDOG,PROPERTY,UNDO,UPDATE. -
Engine symbols:
ENGINEplus one ofLIVE_WEBVIEW,LIVE_CEFSHARP,LIVE_MPVPLAYER,LIVE_VLCPLAYER,LIVE_AURORA,LIVE_NEBULA,LIVE_VEXANA,LIVE_XAVIER. -
Platform symbols (from
Directory.Build.targets, keyed offPlatformTarget):X86,X64,ARM64— each also sets the matchingRuntimeIdentifier(win-x86/win-x64/win-arm64). -
RELEASEgates the private-runtime env-var setup inRuntime.Configure().
- Lifecycle — startup, auto-restore, and Exit vs. Close teardown.
- Commandog Dispatcher — the short-lived command broker.
- IPC — pipe / signal / transmission channels and the command bus.
- Single Instance Mutexes — which processes gate and how.
- Engines Overview — the eight render engines.
- Repository Layout — folder-to-layer mapping.
-
Preprocessor Symbols — per-app / engine / platform
#ifsymbols.
Getting Started
- Installation
- System Requirements
- Quick Start
- Portal Interface Tour
- Updating Sucrose
- Uninstalling Sucrose
Wallpaper Types
Using Sucrose
- Managing Library
- Using Store
- Customizing Wallpaper
- Multi-Monitor
- Wallpaper Cycling
- Choosing Engines
- Performance Rules
- Theme, Tray & Startup
- Discord Rich Presence
Settings Reference
- Settings Overview
- Settings: General
- Settings: Personal
- Settings: Performance
- Settings: Wallpaper
- Settings: System
- Settings: Other
- Settings: All Keys
Creating Wallpapers
- Create Overview
- Create: Step By Step
- Create: Package Format
- Create: Customization Controls
- Create: JS Bridge
- Create: Audio API
- Create: System API
- Create: Property Listener & Filters
- Create: Web Architecture
- Create: Compatibility
- Create: Example Wallpapers
- Create: Sharing & Publishing
Engine Reference
- Engines Overview
- Engine: MpvPlayer
- Engine: VlcPlayer
- Engine: WebView
- Engine: CefSharp
- Engine: Nebula
- Engine: Vexana
- Engine: Xavier
- Engine: Aurora
- Engine Comparison
Automation & Command Line
Architecture & Internals
- Architecture Overview
- Lifecycle
- Commandog Dispatcher
- Single-Instance Mutexes
- IPC
- Backgroundog Service
- Crash Reporting
- Update Internals
- Property Service
- Undo Internals
Data, Files & Diagnostics
Building & Contributing
- Building From Source
- Repository Layout
- Shared Item Projects
- Code Conventions
- Preprocessor Symbols
- Publish Pipeline
- Bundle Installer Internals
- Extending Sucrose
- Contributing
- Translating with Localizer
- Localization Coverage
- Security Policy
- Privacy & Telemetry
Help & Support