⚠️ Stability disclaimer — read this first. What follows is Sucrose's internal IPC command protocol, not a stable, supported public command line. End users never type these strings; the Portal, Launcher tray, engines, and helper services build and emit them automatically. The wire format, the command names, the argument order, and the set of commands are implementation details that can change between versions without notice. There is no compatibility guarantee. Use this page to understand how Sucrose's processes talk to each other and for advanced automation at your own risk — do not build production tooling on top of it.
Sucrose is a multi-process application. One of the two ways its processes coordinate is the command bus: a one-shot, process-launch-based string protocol routed by Sucrose.Commandog.exe (the "Commandog" dispatcher). A command is not a long-lived connection — it is literally "run (or pass arguments to) an executable with a specially-encoded argument string." This page documents the wire format, the full CommandType set, the ArgumentCommandType settings-page targets, and the SchedulerCommandType auto-start sub-commands. For the live data channels (Pipe/Signal/Transmission) that carry audio and system data, see IPC. For who runs the parser, see Commandog-Dispatcher.
Commandog does not use ordinary --flag value syntax. It uses a custom delimited string built from two special Unicode marker characters defined in Sucrose.Memory.Manage.Readonly.General:
| Constant | Value | Code point | Role |
|---|---|---|---|
StartCommandChar |
✔ |
U+2714 (HEAVY CHECK MARK) | Marks the start of a command string |
StartCommand |
"✔" |
U+2714 | String form of the start marker |
ValueSeparatorChar |
✖ |
U+2716 (HEAVY MULTIPLICATION X) | Separates the command name and each value |
ValueSeparator |
"✖" |
U+2716 | String form of the separator |
The layout is:
✔<CommandName>✖<Value0>✖<Value1>✖<Value2>...
A complete example, emitted by an engine to reload the wallpaper:
✔RestartLive✖Unknown
Encoding gotcha. The markers are the literal Unicode characters
✔(U+2714) and✖(U+2716) — not ASCII letters, not the words "check"/"x". Anything reproducing a command externally must emit these exact code points (UTF-8). Commandog setsConsole.InputEncodingandConsole.OutputEncodingto UTF-8 on startup so the markers survive the process boundary.
The dispatcher (Sucrose.Commandog/Helper/Arguments.cs) parses an incoming command like this:
string.Join(" ", args).✔ and to contain ✖. If either check fails, the input is ignored.✔ (take Combined[1..]), then Split('✖').Enum.TryParse<CommandType>(Name, ignoreCase: true, …) — command names are case-insensitive (RestartLive, restartlive, and RESTARTLIVE all parse the same).switch on the parsed CommandType performs the action.Commandog itself does almost no work — it parses the command and either launches the right executable (via Sucrose.Shared.Space.Helper.Processor.Run, a ShellExecute wrapper) or calls a shared helper. It then always Environment.Exit(0) in its finally block, so it is genuinely short-lived. See Commandog-Dispatcher for the full lifecycle.
Each value is converted to the type the command expects by Parse.ArgumentValue<T>:
| Requested type | Conversion |
|---|---|
int |
int.TryParse |
bool |
bool.TryParse |
any enum |
Enum.Parse (e.g. SchedulerCommandType, ArgumentCommandType) |
| anything else | returned as the raw string |
The diagnostic Test command instead uses Miscellaneous.GetType(string), which sniffs bool first, then int, otherwise falls back to string.
The CommandType enum (src/Shared/Sucrose.Shared.Dependency/Enum/CommandType.cs) defines 31 commands. The table below lists every member in enum order, the values it consumes (in order), and what the matching switch case does. "Run(x)" is Processor.Run (ShellExecute); many commands simply open a path or URL.
| # | Command | Values (in order) | Action |
|---|---|---|---|
| 1 | Log |
[0]=path |
Processor.Run(path) — open a log file/folder. |
| 2 | Kill |
[0]=processName |
Processor.Kill(name) — kill all processes by name. |
| 3 | Live |
[0]=path |
Processor.Run(path) — start the live wallpaper engine. |
| 4 | Test |
[0..]=values |
Prints Test Values:, then for each value detects its type and writes the parsed value to the console. Diagnostic only. |
| 5 | Temp |
[0], [1] |
Temporary.Delete(v0, v1) — clear temp/cache. |
| 6 | Wiki |
[0]=url |
Processor.Run(url) — open the wiki URL. |
| 7 | Reset |
[0] |
Reset.Start(v0) — reset settings/app. |
| 8 | Bundle |
[0]=path |
Processor.Run(path) — run the downloaded bundle/installer .exe. |
| 9 | Update |
[0]=updateExe, optional [1] |
If more than one value: Run(v0, v1) (hidden, with arg); else Run(v0). Launches Sucrose.Update.exe. |
| 10 | Import |
[0], [1] |
Import.Start(v0, v1) — import a theme/package. |
| 11 | Export |
[0], [1] |
Export.Start(v0, v1) — export a theme. |
| 12 | Report |
[0]=url |
Processor.Run(url) — open the report page. |
| 13 | Publish |
[0]=url |
Processor.Run(url) — open the publish page. |
| 14 | Startup |
[0]=name, [1]=path, [2]=bool |
WindowsStartup.SetStartup(name, path, enable) — per-user Run-key startup. |
| 15 | Cycyling |
(none used) | Stop live + stop subprocess, Run.Start(), wait 1500 ms; if Live.Run() is false, Run.Start() again. The wallpaper cycling reload. (Spelled "Cycyling" in code.) |
| 16 | Property |
[0]=path |
Processor.Run(path) — launch Sucrose.Property.exe (no theme arg; edits the currently selected wallpaper). |
| 17 | StartupM |
[0], [1], [2]=bool |
WindowsStartupMachine.SetStartup(...) — machine-wide startup. |
| 18 | StartupP |
[0], [1]=bool |
WindowsStartupPriority.SetStartup(...) — startup priority/approved. |
| 19 | Official |
[0]=url |
Processor.Run(url). |
| 20 | Watchdog |
[0]=watchdogExe, [1]=encodedPayload |
If exactly two values: Run(v0, v1) (hidden). Launches Sucrose.Watchdog.exe with the Base64 crash payload. |
| 21 | Interface |
[0]=portalExe, optional [1]=settingType |
If more than one value: Run(v0, v1); else Run(v0). Opens the Portal, optionally on a specific settings page (see ArgumentCommandType). |
| 22 | PropertyA |
[0], [1] |
Run(v0, v1) — launch Sucrose.Property.exe with an argument (a specific selected theme). |
| 23 | Reportdog |
[0]=reportdogExe |
Run(v0, string.Empty) — launch Sucrose.Reportdog.exe. |
| 24 | Scheduler |
[0]=SchedulerCommandType, [1]=appPath (Create only) |
Routes to a Task Scheduler operation — see SchedulerCommandType. |
| 25 | Repository |
[0]=url |
Processor.Run(url). |
| 26 | Versioning |
[0]=folder, [1]=version, [2]=bool |
Delete.Folder(folder, version, bool) — delete old-version folders (used by the Launcher "Version" command). |
| 27 | Discussions |
[0]=url |
Processor.Run(url). |
| 28 | RestartLive |
(none used) | Stop live + subprocess, kill Sucrose.Backgroundog.exe, Run.Start(), wait 1500 ms, retry if not running. The wallpaper reload command. |
| 29 | Backgroundog |
[0]=backgroundogExe |
Run(v0, string.Empty) — launch the background system-status/audio service. |
| 30 | QuotingGoogle |
[0]=url |
Processor.Run(url). |
| 31 | QuotingTranslate |
[0]=url |
Processor.Run(url). |
flowchart LR
Emitter["Emitter<br/>Portal / Launcher tray / engine"] -->|"builds ✔Command✖value"| Spawn["spawn<br/>Sucrose.Commandog.exe"]
Spawn --> Parse{"starts with ✔<br/>and contains ✖ ?"}
Parse -->|no| Ignore["ignored"]
Parse -->|yes| Switch["Enum.TryParse<CommandType><br/>switch on command"]
Switch --> Run["Processor.Run /<br/>Processor.Kill"]
Switch --> Helper["shared helper<br/>Run.Start / Import / Reset / Scheduler"]
Run --> Target["target .exe launches"]
Helper --> Target
Target --> Done["Commandog Environment.Exit(0)"]
When the Interface command opens the Portal on a specific settings page, the second value is an ArgumentCommandType member (parsed as an enum). Only two of the seven members are actually honored by the Portal — the rest fall back to the Library page:
| Member | Opens |
|---|---|
OtherSetting |
Not handled — Portal falls back to the Library page |
DonateSetting |
Not handled — Portal falls back to the Library page |
SystemSetting |
Settings-System |
GeneralSetting |
Settings-General |
PersonalSetting |
Not handled — Portal falls back to the Library page |
WallpaperSetting |
Not handled — Portal falls back to the Library page |
PerformanceSetting |
Not handled — Portal falls back to the Library page |
Note.
MainWindow.xaml.csonly branches onSystemSettingandGeneralSetting; any other second value (or none) navigates to the default Library page (SPVPLP). So emitting e.g.✔Interface✖<PortalPath>✖OtherSettingopens the Library page, not a settings page.
Example: the Launcher tray "Settings" action emits
✔Interface✖<PortalPath>✖GeneralSetting
which opens the Portal directly on the General settings page.
The Scheduler command manages a Windows Task Scheduler task — Sucrose's preferred auto-start-on-logon mechanism (distinct from the Run-key Startup/StartupM/StartupP commands). The first value is a SchedulerCommandType member:
| Member | Routes to | Notes |
|---|---|---|
Create |
Scheduler.CreateTask(Values[1]) |
Creates the task; Values[1] is the application path to run. |
Enable |
Scheduler.EnableTask() |
Enables the existing task. |
Delete |
Scheduler.DeleteTask() |
Deletes the task (use this to fully remove auto-start). |
Disable |
Scheduler.DisableTask() |
Disables the task without deleting it. |
The task itself (Sucrose.Commandog/Helper/Scheduler.cs + Sucrose.Memory/Manage/Readonly/Scheduler.cs):
| Property | Value |
|---|---|
| Task name | Autorun for Sucrose |
| Task description | Sucrose Wallpaper Engine |
| Task folder | \Sucrose\ (root folder named Sucrose) |
| Trigger | LogonTrigger, scoped to the current user (WindowsIdentity.GetCurrent().Name) |
| Action | ExecAction(Application) |
StopIfGoingOnBatteries |
false |
DisallowStartIfOnBatteries |
false |
ExecutionTimeLimit |
TimeSpan.Zero (no limit) |
Backed by the Microsoft.Win32.TaskScheduler library. Because Sucrose starts via a scheduled task rather than a registry Run entry, you will not find it in the typical HKCU\…\Run startup list — see Troubleshooting-Settings-Startup-GPU.
Example — create the logon task:
✔Scheduler✖Create✖<full path to the app to run>
Example — remove the logon task:
✔Scheduler✖Delete
Commands are emitted by the UI and services, never by the user directly. Representative emitters (src/Shared/Sucrose.Shared.Launcher/Command/*.cs and others):
| Emitter | Command emitted | Purpose |
|---|---|---|
Launcher tray → Reload (Reload.cs) |
✔RestartLive✖Unknown |
Reload the wallpaper |
Launcher tray → Update (Update.cs) |
✔Update✖<UpdatePath> |
Launch the updater |
Launcher tray → Settings (Setting.cs) |
✔Interface✖<PortalPath>✖GeneralSetting |
Open Portal on General settings |
Launcher tray → Interface (Interface.cs) |
✔Interface✖<PortalPath> |
Open the Portal |
Launcher tray → Property (Property.cs) |
✔Property✖<PropertyPath> |
Open the per-wallpaper property editor |
Launcher tray → Reportdog (Reportdog.cs) |
✔Reportdog✖<ReportdogPath> |
Launch the report uploader |
Launcher → Version cleanup (Version.cs) |
✔Versioning✖<%LocalAppData%\Sucrose>✖<entryVersion>✖false |
Delete old-version folders |
Crash path (Sucrose.Shared.Space.Helper.Watchdog.cs) |
✔Watchdog✖<WatchdogPath>✖<Base64 payload> |
Show the crash dialog / write the report |
Updater (Sucrose.Update/View/MainWindow.xaml.cs) |
✔Bundle✖<installerPath> |
Launch the downloaded installer |
Engine (Sucrose.Shared.Engine/Event/Handler.cs) |
✔RestartLive✖Unknown |
Reload after an engine-side event |
Some Launcher commands (Close.cs, Engine.cs, Report.cs) act locally — they kill processes or show a dialog directly and do not go through Commandog. Feedback.cs is fully commented out (no feedback dialog ships).
RestartLive is the reload (it also kills Sucrose.Backgroundog.exe); Cycyling (note the spelling) is the cycling reload used by Wallpaper-Cycling; both go through Commandog.Backgroundog, Watchdog, Reportdog, and Property exist mainly to launch the corresponding service .exe. Backgroundog auto-exits when there is no live wallpaper (after a few retries), so it is started on demand via ✔Backgroundog✖….Watchdog command's second value is a Base64-encoded Application✖SerializedException✖Show✖LogPath block — see Crash-Reporting.CommandType and the live-channel CommunicationType enums are declared internal. They are not exposed as a public API.Startup/Scheduler commands