Skip to content

Architecture Overview

Taiizor edited this page Jun 19, 2026 · 4 revisions

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 &amp; Features"]) --> Undo["Sucrose.Undo.exe<br/>uninstaller"]
    Engine -. spawns .-> Children["msedgewebview2 /<br/>CefSharp.BrowserSubprocess"]
Loading

Contents

The process roster

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.

Why separate processes

  • 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.

The three coupling mechanisms

  1. Process spawning via Commandog. Most cross-process actions are not direct Process.Start calls — they are routed through Sucrose.Commandog.exe, which is spawned with a single encoded argument string (✔<Command>✖<value>...), performs the action, and exits. See Commandog Dispatcher and Command Reference.
  2. 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.
  3. 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.

Physical folders vs. logical layers

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.

Who spawns whom

  • 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 spawning Backgroundog (✔Backgroundog✖<Backgroundog>) when PerformanceCounter is on;
    • spawns Reportdog to flush pending reports;
    • runs a silent update check (spawns Update) when auto-update is on.
  • Tray actions route through Commandog: Open → ✔Interface✖<Portal>, Customize → ✔Property✖<Property>, Reload → ✔RestartLive✖Unknown, etc.
  • Any process that throws spawns Watchdog through Commandog with a Base64 exception payload; Reportdog later uploads the report.
  • Sucrose.Undo.exe is 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.

Common per-process startup configuration

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.Runtime to PATH. Debug builds use the machine's installed runtime.
  • SSDHG.Configure() (Shared.Dependency.Helper.Graphic) — calls EnsureHighPerformance(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.

Preprocessor symbols

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: ENGINE plus one of LIVE_WEBVIEW, LIVE_CEFSHARP, LIVE_MPVPLAYER, LIVE_VLCPLAYER, LIVE_AURORA, LIVE_NEBULA, LIVE_VEXANA, LIVE_XAVIER.
  • Platform symbols (from Directory.Build.targets, keyed off PlatformTarget): X86, X64, ARM64 — each also sets the matching RuntimeIdentifier (win-x86 / win-x64 / win-arm64).
  • RELEASE gates the private-runtime env-var setup in Runtime.Configure().

See also

Home

Getting Started

Wallpaper Types

Using Sucrose

Settings Reference

Creating Wallpapers

Engine Reference

Automation & Command Line

Architecture & Internals

Data, Files & Diagnostics

Building & Contributing

Help & Support

Clone this wiki locally