<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Recent changes to IPC</title><link>https://sourceforge.net/p/sucrose/wiki/IPC/</link><description>Recent changes to IPC</description><atom:link href="https://sourceforge.net/p/sucrose/wiki/IPC/feed" rel="self"/><language>en</language><lastBuildDate>Sat, 04 Jul 2026 04:15:49 -0000</lastBuildDate><atom:link href="https://sourceforge.net/p/sucrose/wiki/IPC/feed" rel="self" type="application/rss+xml"/><item><title>IPC modified by Bayram Emekli</title><link>https://sourceforge.net/p/sucrose/wiki/IPC/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v2
+++ v3
@@ -40,7 +40,7 @@

 The three live-data transports are **functionally interchangeable** and carry the **same payload object**. The active transport is chosen by the `CommunicationType` setting. Both `CommunicationType` and `CommandType` enums are `internal`.

-&amp;gt; The Backgroundog **data channel is web-engine-only** — it is compiled under `#if LIVE_WEBVIEW || LIVE_CEFSHARP`. MpvPlayer, Aurora, Nebula, Vexana, and Xavier do not consume this data channel.
+&amp;gt; The Backgroundog **data channel is web-engine-only** — it is compiled under `#if LIVE_WEBVIEW || LIVE_CEFSHARP`. MpvPlayer, VlcPlayer, Aurora, Nebula, Vexana, and Xavier do not consume this data channel.

 Source libraries: `Sucrose.Pipe`, `Sucrose.Signal`, `Sucrose.Transmission` (under `src/Library/`); the decoding handler services live in `Sucrose.Shared.Pipe`, `Sucrose.Shared.Signal`, `Sucrose.Shared.Transmission` (under `src/Shared/`).

&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Bayram Emekli</dc:creator><pubDate>Sat, 04 Jul 2026 04:15:49 -0000</pubDate><guid>https://sourceforge.netf505e9d7c8aa6b3d08d455c7bca0c4bf14169df2</guid></item><item><title>IPC modified by Bayram Emekli</title><link>https://sourceforge.net/p/sucrose/wiki/IPC/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v1
+++ v2
@@ -2,7 +2,20 @@

 Sucrose's separate Windows processes coordinate through **four** distinct mechanisms that fall into two categories. The first category is **live-data channels** — three functionally interchangeable transports (**Pipe**, **Signal**, **Transmission**) that push live system/audio data from `Backgroundog` to the running web engine, plus a tray-control channel that lets the Portal and Backgroundog drive the Launcher's tray icon. The second category is the **command bus** — the one-shot, process-launch string protocol handled by `Sucrose.Commandog`, described separately on the [Commandog Dispatcher](Commandog-Dispatcher) and [Command Reference](Command-Reference) pages. This page is the developer reference for the live-data channels: the exact pipe/signal/port names, the shared payload schema, and the end-to-end flow.

-&amp;gt; 🖼️ **Diagram needed:** Producer (Backgroundog) → one of {Pipe, Signal, Transmission} → Consumer (WebView/CefSharp engine) → `ExecuteScriptAsync` → JavaScript in the wallpaper page. Plus the tray-control side channel (Portal/Backgroundog → Signal → Launcher → TrayIconManager).

+    :::mermaid
+    flowchart LR
+        BG["Sucrose.Backgroundog&lt;br/&gt;Specification.Start()"]
+        BG --&amp;gt;|PipeRequired| Pipe["Named Pipe&lt;br/&gt;...Backgroundog.Pipe"]
+        BG --&amp;gt;|SignalRequired| Signal["Signal file&lt;br/&gt;Backgroundog-&amp;lt;guid&amp;gt;.sgnl"]
+        BG --&amp;gt;|TransmissionRequired| Trans["TCP loopback&lt;br/&gt;127.0.0.1 : TransmissionPort"]
+        Pipe --&amp;gt; Eng
+        Signal --&amp;gt; Eng
+        Trans --&amp;gt; Eng
+        Eng["WebView / CefSharp engine&lt;br/&gt;Web.StartCompatible()"] --&amp;gt; Exec["ExecuteScriptAsync"]
+        Exec --&amp;gt; JS["Wallpaper JavaScript&lt;br/&gt;audio + system API"]
+    
+        Prod2["Portal / Backgroundog"] --&amp;gt;|"Launcher flags: Show / Hide / Icon / Release"| Sig2["Signal: Launcher.sgnl"]
+        Sig2 --&amp;gt; Launcher2["Launcher&lt;br/&gt;TrayIconManager"]

 ## Contents

&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Bayram Emekli</dc:creator><pubDate>Sat, 04 Jul 2026 04:15:43 -0000</pubDate><guid>https://sourceforge.net2ac79298eb49a20c93438e2f1e03e8b805688fea</guid></item><item><title>IPC modified by Bayram Emekli</title><link>https://sourceforge.net/p/sucrose/wiki/IPC/</link><description>&lt;div class="markdown_content"&gt;&lt;h1 id="h-ipc-inter-process-communication"&gt;IPC (Inter-Process Communication)&lt;/h1&gt;
&lt;p&gt;Sucrose's separate Windows processes coordinate through &lt;strong&gt;four&lt;/strong&gt; distinct mechanisms that fall into two categories. The first category is &lt;strong&gt;live-data channels&lt;/strong&gt; — three functionally interchangeable transports (&lt;strong&gt;Pipe&lt;/strong&gt;, &lt;strong&gt;Signal&lt;/strong&gt;, &lt;strong&gt;Transmission&lt;/strong&gt;) that push live system/audio data from &lt;code&gt;Backgroundog&lt;/code&gt; to the running web engine, plus a tray-control channel that lets the Portal and Backgroundog drive the Launcher's tray icon. The second category is the &lt;strong&gt;command bus&lt;/strong&gt; — the one-shot, process-launch string protocol handled by &lt;code&gt;Sucrose.Commandog&lt;/code&gt;, described separately on the &lt;a href="./Commandog-Dispatcher"&gt;Commandog Dispatcher&lt;/a&gt; and &lt;a href="./Command-Reference"&gt;Command Reference&lt;/a&gt; pages. This page is the developer reference for the live-data channels: the exact pipe/signal/port names, the shared payload schema, and the end-to-end flow.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;🖼️ &lt;strong&gt;Diagram needed:&lt;/strong&gt; Producer (Backgroundog) → one of {Pipe, Signal, Transmission} → Consumer (WebView/CefSharp engine) → &lt;code&gt;ExecuteScriptAsync&lt;/code&gt; → JavaScript in the wallpaper page. Plus the tray-control side channel (Portal/Backgroundog → Signal → Launcher → TrayIconManager).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="h-contents"&gt;Contents&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#two-categories-of-ipc"&gt;Two categories of IPC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#the-shared-message-payloads"&gt;The shared message payloads&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#transport-a--named-pipe"&gt;Transport A — Named Pipe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#transport-b--signal-filesystem"&gt;Transport B — Signal (filesystem)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#transport-c--transmission-tcp-loopback"&gt;Transport C — Transmission (TCP loopback)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#transport-selection-communicationtype"&gt;Transport selection: CommunicationType&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#end-to-end-live-data-flow"&gt;End-to-end live-data flow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#tray-control-flow"&gt;Tray-control flow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#gotchas"&gt;Gotchas&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#see-also"&gt;See also&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="h-two-categories-of-ipc"&gt;Two categories of IPC&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concern&lt;/th&gt;
&lt;th&gt;Mechanism&lt;/th&gt;
&lt;th&gt;Direction&lt;/th&gt;
&lt;th&gt;Default&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Push live system + audio data to the running engine&lt;/td&gt;
&lt;td&gt;Pipe &lt;strong&gt;or&lt;/strong&gt; Signal &lt;strong&gt;or&lt;/strong&gt; Transmission (user-selectable)&lt;/td&gt;
&lt;td&gt;Backgroundog (producer) → Engine (consumer)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Transmission&lt;/strong&gt; is the default &lt;code&gt;CommunicationType&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Control the Launcher tray icon (show/hide/release/icon)&lt;/td&gt;
&lt;td&gt;Signal / Pipe / Transmission (&lt;code&gt;Launcher&lt;/code&gt; interface)&lt;/td&gt;
&lt;td&gt;Portal / Backgroundog (producer) → Launcher (consumer)&lt;/td&gt;
&lt;td&gt;Launcher listens on &lt;strong&gt;Signal&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fire-and-forget commands (set/restart wallpaper, kill, import/export, open Portal, scheduler, etc.)&lt;/td&gt;
&lt;td&gt;Command bus (&lt;code&gt;CommandType&lt;/code&gt;, string args via process args)&lt;/td&gt;
&lt;td&gt;Any process → target &lt;code&gt;.exe&lt;/code&gt; (often Commandog)&lt;/td&gt;
&lt;td&gt;n/a (launch-based)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The three live-data transports are &lt;strong&gt;functionally interchangeable&lt;/strong&gt; and carry the &lt;strong&gt;same payload object&lt;/strong&gt;. The active transport is chosen by the &lt;code&gt;CommunicationType&lt;/code&gt; setting. Both &lt;code&gt;CommunicationType&lt;/code&gt; and &lt;code&gt;CommandType&lt;/code&gt; enums are &lt;code&gt;internal&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The Backgroundog &lt;strong&gt;data channel is web-engine-only&lt;/strong&gt; — it is compiled under &lt;code&gt;#if LIVE_WEBVIEW || LIVE_CEFSHARP&lt;/code&gt;. MpvPlayer, Aurora, Nebula, Vexana, and Xavier do not consume this data channel.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Source libraries: &lt;code&gt;Sucrose.Pipe&lt;/code&gt;, &lt;code&gt;Sucrose.Signal&lt;/code&gt;, &lt;code&gt;Sucrose.Transmission&lt;/code&gt; (under &lt;code&gt;src/Library/&lt;/code&gt;); the decoding handler services live in &lt;code&gt;Sucrose.Shared.Pipe&lt;/code&gt;, &lt;code&gt;Sucrose.Shared.Signal&lt;/code&gt;, &lt;code&gt;Sucrose.Shared.Transmission&lt;/code&gt; (under &lt;code&gt;src/Shared/&lt;/code&gt;).&lt;/p&gt;
&lt;h2 id="h-the-shared-message-payloads"&gt;The shared message payloads&lt;/h2&gt;
&lt;p&gt;Every transport defines &lt;strong&gt;identical&lt;/strong&gt; &lt;code&gt;Interface/Backgroundog.cs&lt;/code&gt; and &lt;code&gt;Interface/Launcher.cs&lt;/code&gt; classes (one copy per library; the namespaces differ but the shapes are identical). They are JSON-serialized with Newtonsoft.Json, &lt;code&gt;TypeNameHandling = None&lt;/code&gt;, &lt;code&gt;Formatting = None&lt;/code&gt; — &lt;strong&gt;plain JSON text, one message per line&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id="h-backgroundog-payload-live-system-audio-data"&gt;&lt;code&gt;Backgroundog&lt;/code&gt; payload (live system + audio data)&lt;/h3&gt;
&lt;p&gt;Ten nullable &lt;code&gt;Newtonsoft.Json.Linq.JObject&lt;/code&gt; properties:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Bios, Date, Audio, Memory, Battery, Graphic, Network, Storage, Processor, Motherboard
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;On receipt, each non-null sub-object is re-serialized with &lt;code&gt;Formatting.Indented&lt;/code&gt; and stored into the engine's static &lt;code&gt;Sucrose.Shared.Engine.Manage.Internal&lt;/code&gt; fields: &lt;code&gt;BiosData, DateData, AudioData, MemoryData, BatteryData, GraphicData, NetworkData, StorageData, ProcessorData, MotherboardData&lt;/code&gt; (all JSON strings). The &lt;strong&gt;&lt;code&gt;Audio&lt;/code&gt;&lt;/strong&gt; field is the audio-reactive data — the audio-visualization channel for Web wallpapers. For the inner field schema of each section, see &lt;a href="./Create-System-API"&gt;Create System API&lt;/a&gt; and &lt;a href="./Create-Audio-API"&gt;Create Audio API&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="h-launcher-payload-tray-icon-control"&gt;&lt;code&gt;Launcher&lt;/code&gt; payload (tray-icon control)&lt;/h3&gt;
&lt;p&gt;Four &lt;code&gt;bool&lt;/code&gt; flags, all default &lt;code&gt;false&lt;/code&gt;:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;Hide&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Icon&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Show&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Release&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The handler (&lt;code&gt;LauncherSignalService&lt;/code&gt; / &lt;code&gt;LauncherPipeService&lt;/code&gt; / &lt;code&gt;LauncherTransmissionService&lt;/code&gt;) maps them to &lt;code&gt;SSLMI.TrayIconManager&lt;/code&gt;:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Flag&lt;/th&gt;
&lt;th&gt;Effect&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Hide&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TrayIconManager.Hide()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Show&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TrayIconManager.Show()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Release&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TrayIconManager.Release()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Icon&lt;/code&gt; (always evaluated)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;TrayIconManager.Icon(Data.Icon)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="h-transport-a-named-pipe"&gt;Transport A — Named Pipe&lt;/h2&gt;
&lt;p&gt;Pipe names (exact), defined in &lt;code&gt;Sucrose.Pipe.Manage.Internal&lt;/code&gt;:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;LauncherManager&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PipeT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sucrose.Wallpaper.Engine.Launcher.Pipe"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;BackgroundogManager&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PipeT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sucrose.Wallpaper.Engine.Backgroundog.Pipe"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Server name / host:&lt;/strong&gt; &lt;code&gt;Sucrose.Memory.Manage.Readonly.General.PipeServerName = "."&lt;/code&gt; (the local machine).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Server&lt;/strong&gt; (&lt;code&gt;PipeServer.cs&lt;/code&gt;): &lt;code&gt;NamedPipeServerStream(pipeName, PipeDirection.In, 10, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)&lt;/code&gt; — max &lt;strong&gt;10&lt;/strong&gt; server instances. Reads line-by-line; each line raises &lt;code&gt;MessageReceived&lt;/code&gt; with &lt;code&gt;MessageReceivedEventArgs { Message }&lt;/code&gt;. Accept timeout 5 s, read timeout 15 s; on error it recreates the pipe with a 1 s backoff.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Client&lt;/strong&gt; (&lt;code&gt;PipeClient.cs&lt;/code&gt;): &lt;code&gt;NamedPipeClientStream(".", pipeName, PipeDirection.Out, PipeOptions.Asynchronous)&lt;/code&gt;, connect timeout 5 s; writes one line per message with &lt;code&gt;AutoFlush = true&lt;/code&gt;, guarded by a &lt;code&gt;SemaphoreSlim(1,1)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;PipeT&lt;/code&gt; facade:&lt;/strong&gt; &lt;code&gt;StartClient()&lt;/code&gt;, &lt;code&gt;StartClient(string Message)&lt;/code&gt;, &lt;code&gt;StartServer()&lt;/code&gt;, &lt;code&gt;StopClient()&lt;/code&gt;, &lt;code&gt;StopServer()&lt;/code&gt;, &lt;code&gt;DisposeClient()&lt;/code&gt;, &lt;code&gt;DisposeServer()&lt;/code&gt;, &lt;code&gt;event MessageReceived&lt;/code&gt;. &lt;code&gt;StartClientWithRetry&lt;/code&gt; uses exponential backoff (&lt;code&gt;2^i&lt;/code&gt; seconds, default 3 retries).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The pipe is &lt;strong&gt;half-duplex / one-way&lt;/strong&gt; here (producer = client/Out, engine = server/In); there is no reply channel. Transmission mode is &lt;code&gt;Byte&lt;/code&gt;, but messages are newline-delimited JSON text. When this transport is active the engine sets setting &lt;code&gt;PipeRequired = true&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="h-transport-b-signal-filesystem"&gt;Transport B — Signal (filesystem)&lt;/h2&gt;
&lt;p&gt;The simplest, most robust transport: write a JSON file, watch a folder. Channel file names (exact), defined in &lt;code&gt;Sucrose.Signal.Manage.Internal&lt;/code&gt;:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;LauncherManager&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SignalT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Launcher.sgnl"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;BackgroundogManager&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SignalT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Backgroundog.sgnl"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Directory:&lt;/strong&gt; &lt;code&gt;SignalT.Source&lt;/code&gt; = &lt;code&gt;%AppData%\Sucrose\Cache\SignalT&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Write&lt;/strong&gt; (&lt;code&gt;FileSave&amp;lt;T&amp;gt;&lt;/code&gt;): serialize (&lt;code&gt;TypeNameHandling = None&lt;/code&gt;, &lt;code&gt;Formatting = None&lt;/code&gt;) to a &lt;strong&gt;unique&lt;/strong&gt; file &lt;code&gt;"{nameWithoutExt}-{Guid.NewGuid()}{ext}"&lt;/code&gt;, e.g. &lt;code&gt;Backgroundog-&amp;lt;guid&amp;gt;.sgnl&lt;/code&gt;. The write (&lt;code&gt;Helper/Writer.cs&lt;/code&gt;) uses a cross-process named &lt;code&gt;Mutex&lt;/code&gt; &lt;code&gt;"SignalWriter_{fileName}"&lt;/code&gt;, 5 s timeout, 3 retries (100 ms apart), &lt;code&gt;FileShare.None&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Watch&lt;/strong&gt; (&lt;code&gt;StartChannel(FileSystemEventHandler)&lt;/code&gt;): a &lt;code&gt;FileSystemWatcher&lt;/code&gt; on &lt;code&gt;Source&lt;/code&gt;, &lt;code&gt;Filter = "*.*"&lt;/code&gt;, &lt;code&gt;InternalBufferSize = 64 KB&lt;/code&gt;, &lt;code&gt;NotifyFilter = LastWrite | FileName | DirectoryName&lt;/code&gt;. On &lt;code&gt;Created&lt;/code&gt;, files whose name &lt;em&gt;contains&lt;/em&gt; the channel base name fire the handler. On startup it deletes old matching files; it handles &lt;code&gt;InternalBufferOverflowException&lt;/code&gt; by toggling &lt;code&gt;EnableRaisingEvents&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Read&lt;/strong&gt; (&lt;code&gt;FileRead&amp;lt;T&amp;gt;&lt;/code&gt;): a small random 5–50 ms delay to reduce contention, then deserialize via &lt;code&gt;Helper/Reader.cs&lt;/code&gt; with named &lt;code&gt;Mutex&lt;/code&gt; &lt;code&gt;"SignalReader_{fileName}"&lt;/code&gt;, 5 s timeout, 3 retries, &lt;code&gt;FileShare.Read&lt;/code&gt;. If &lt;code&gt;Delete&lt;/code&gt; is true, deletion is scheduled on a 3 s timer; corrupt JSON also triggers deletion.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Delete&lt;/strong&gt; (&lt;code&gt;Helper/Deleter.cs&lt;/code&gt;): set attributes to &lt;code&gt;Normal&lt;/code&gt;, delete, 3 retries with 50–200 ms random backoff, swallow failures.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code&gt;.sgnl&lt;/code&gt; extension is the signal marker. This is the &lt;strong&gt;only&lt;/strong&gt; transport the Launcher actually uses for tray control (&lt;code&gt;App.xaml.cs&lt;/code&gt; → &lt;code&gt;LauncherManager.StartChannel&lt;/code&gt;). When this transport is active the engine sets setting &lt;code&gt;SignalRequired = true&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="h-transport-c-transmission-tcp-loopback"&gt;Transport C — Transmission (TCP loopback)&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Host:&lt;/strong&gt; &lt;code&gt;Sucrose.Memory.Manage.Readonly.General.Loopback = IPAddress.Loopback&lt;/code&gt; (127.0.0.1).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Port:&lt;/strong&gt; dynamically allocated at engine startup via &lt;code&gt;Sucrose.Shared.Space.Helper.Port.Available(Loopback)&lt;/code&gt; and saved to the setting &lt;code&gt;TransmissionPort&lt;/code&gt;; the producer reads &lt;code&gt;TransmissionPort&lt;/code&gt; back to connect.&lt;/li&gt;
&lt;li&gt;Unlike Pipe/Signal, &lt;code&gt;Transmission.Manage.Internal.{LauncherManager, BackgroundogManager}&lt;/code&gt; are &lt;strong&gt;not&lt;/strong&gt; pre-constructed — they are created on demand: &lt;code&gt;new TransmissionT(Loopback, port)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Server&lt;/strong&gt; (&lt;code&gt;TransmissionServer.cs&lt;/code&gt;): &lt;code&gt;TcpListener(host, port)&lt;/code&gt;, accepts one client, reads newline-delimited messages. Accept timeout 5 s, read timeout 15 s; keep-alive on (&lt;code&gt;TcpKeepAliveTime=10&lt;/code&gt;, &lt;code&gt;TcpKeepAliveInterval=2&lt;/code&gt;), &lt;code&gt;SendTimeout=5000&lt;/code&gt;, &lt;code&gt;ReceiveTimeout=15000&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Client&lt;/strong&gt; (&lt;code&gt;TransmissionClient.cs&lt;/code&gt;): &lt;code&gt;TcpClient.ConnectAsync(host, port)&lt;/code&gt;, connect timeout 5 s; &lt;code&gt;SendTimeout=2500&lt;/code&gt;, &lt;code&gt;ReceiveTimeout=5000&lt;/code&gt;; one line per message with &lt;code&gt;AutoFlush = true&lt;/code&gt;, guarded by &lt;code&gt;SemaphoreSlim(1,1)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;TransmissionT&lt;/code&gt; facade:&lt;/strong&gt; same API surface as &lt;code&gt;PipeT&lt;/code&gt;, plus a public &lt;code&gt;int Port { get; }&lt;/code&gt;. Retry/backoff identical to &lt;code&gt;PipeT&lt;/code&gt; (exponential, retries on &lt;code&gt;SocketException&lt;/code&gt; / &lt;code&gt;TimeoutException&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Loopback only — no remote exposure. This is the &lt;strong&gt;default&lt;/strong&gt; &lt;code&gt;CommunicationType&lt;/code&gt;. When active, the engine sets settings &lt;code&gt;TransmissionRequired = true&lt;/code&gt; and &lt;code&gt;TransmissionPort = &amp;lt;port&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="h-transport-selection-communicationtype"&gt;Transport selection: CommunicationType&lt;/h2&gt;
&lt;p&gt;Enum &lt;code&gt;Sucrose.Shared.Dependency.Enum.CommunicationType&lt;/code&gt; (internal):&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Pipe, Signal, Transmission
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Read through &lt;code&gt;Sucrose.Shared.Dependency.Manage.Manager.Backgroundog.CommunicationType&lt;/code&gt;, which calls &lt;code&gt;BackgroundogSettingManager.GetSetting(SMMCB.CommunicationType, /*default*/ Transmission)&lt;/code&gt;. The setting key constant is &lt;code&gt;Sucrose.Memory.Manage.Constant.Backgroundog.CommunicationType = "CommunicationType"&lt;/code&gt;. The engine (&lt;code&gt;Web.cs::StartCompatible()&lt;/code&gt;) branches on it to spin up exactly one server.&lt;/p&gt;
&lt;p&gt;Related setting keys (all in &lt;code&gt;Sucrose.Memory.Manage.Constant.Backgroundog&lt;/code&gt;): &lt;code&gt;PipeRequired&lt;/code&gt;, &lt;code&gt;SignalRequired&lt;/code&gt;, &lt;code&gt;TransmissionRequired&lt;/code&gt;, &lt;code&gt;TransmissionPort&lt;/code&gt;, &lt;code&gt;AudioRequired&lt;/code&gt;, &lt;code&gt;CommunicationType&lt;/code&gt;. Producer and consumer must independently agree: the engine sets &lt;code&gt;*Required&lt;/code&gt; / &lt;code&gt;TransmissionPort&lt;/code&gt;, and the producer reads them.&lt;/p&gt;
&lt;h2 id="h-end-to-end-live-data-flow"&gt;End-to-end live-data flow&lt;/h2&gt;
&lt;p&gt;The canonical flow — "audio-reactive / system data reaches a Web wallpaper":&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;[Sucrose.Backgroundog process]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;Specification.Start()&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;collects Bios/Date/Audio/Memory/Battery/Graphic/Network/Storage/Processor/Motherboard (JObject)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;builds Interface.Backgroundog, JSON-serializes (TypeNameHandling&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;None)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;branches by which *Required flag is set&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="na"&gt;PipeRequired         -&amp;gt; BackgroundogManager.StartClient(json)  (pipe "Sucrose.Wallpaper.Engine.Backgroundog.Pipe")&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="na"&gt;SignalRequired       -&amp;gt; BackgroundogManager.FileSave(payload)  (writes Backgroundog-&amp;lt;guid&amp;gt;.sgnl)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="na"&gt;TransmissionRequired -&amp;gt; BackgroundogManager.StartClient(json)  (TCP loopback&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;TransmissionPort)&lt;/span&gt;
&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="na"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="na"&gt;v   (one of three transports — must match the engine's choice)&lt;/span&gt;
&lt;span class="k"&gt;[Sucrose.Live.WebView | Sucrose.Live.CefSharp process]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;Web.StartCompatible()  switch(CommunicationType)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="na"&gt;Pipe&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="s"&gt;MessageReceived += Handler&lt;/span&gt;&lt;span class="c1"&gt;; StartServer()&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="na"&gt;Signal&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="s"&gt;StartChannel(Handler)&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="na"&gt;Transmission&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;new TransmissionT(Loopback, Port.Available)&lt;/span&gt;&lt;span class="c1"&gt;; StartServer()&lt;/span&gt;
&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="na"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="na"&gt;v&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;Backgroundog{Pipe|Signal|Transmission}Service.Handler(e)&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="na"&gt;JSON -&amp;gt; Interface.Backgroundog&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="na"&gt;for each non-null field&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;lt;X&amp;gt;Data = JsonConvert.SerializeObject(field, Indented)&lt;/span&gt;
&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="na"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="na"&gt;v&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;Compatible.ExecuteTask(...) -&amp;gt; Compatible.ExecuteNormal(...)&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="na"&gt;for each Compatible.&amp;lt;Hook&amp;gt; placeholder, string.Format(hook, &amp;lt;X&amp;gt;Data) -&amp;gt; ExecuteScriptAsync(js)&lt;/span&gt;
&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="na"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="na"&gt;v&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;JavaScript inside the wallpaper page receives the data (audio API, system status API)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;See &lt;a href="./Create-Web-Architecture"&gt;Create Web Architecture&lt;/a&gt; for the JS-bridge side of this flow.&lt;/p&gt;
&lt;h2 id="h-tray-control-flow"&gt;Tray-control flow&lt;/h2&gt;
&lt;p&gt;Simpler: a producer writes &lt;code&gt;Interface.Launcher { Show=true }&lt;/code&gt; (e.g. &lt;code&gt;LauncherManager.FileSave&lt;/code&gt;) → the Launcher's &lt;code&gt;FileSystemWatcher&lt;/code&gt; fires → &lt;code&gt;LauncherSignalService.Handler&lt;/code&gt; → &lt;code&gt;TrayIconManager.Show()&lt;/code&gt;. Producers include &lt;code&gt;Backgroundog/Helper/Performance.cs&lt;/code&gt; (&lt;code&gt;Icon=true&lt;/code&gt;), &lt;code&gt;Helper/Condition.cs&lt;/code&gt; (&lt;code&gt;Icon=false&lt;/code&gt;), and &lt;code&gt;Portal/.../GeneralSettingViewModel.cs&lt;/code&gt; (&lt;code&gt;Show&lt;/code&gt; / &lt;code&gt;Hide&lt;/code&gt;).&lt;/p&gt;
&lt;h2 id="h-gotchas"&gt;Gotchas&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The Backgroundog data channel is &lt;strong&gt;web-engine-only&lt;/strong&gt; (&lt;code&gt;#if LIVE_WEBVIEW || LIVE_CEFSHARP&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The three transports carry the &lt;strong&gt;exact same JSON payload&lt;/strong&gt;; only the carrier differs.&lt;/li&gt;
&lt;li&gt;The Signal transport writes a &lt;strong&gt;new GUID-named file per message&lt;/strong&gt; and self-cleans on a 3 s timer — files can momentarily pile up under &lt;code&gt;%AppData%\Sucrose\Cache\SignalT&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;All Signal file I/O is guarded by named mutexes (&lt;code&gt;SignalReader_*&lt;/code&gt;, &lt;code&gt;SignalWriter_*&lt;/code&gt;) with abandoned-mutex handling.&lt;/li&gt;
&lt;li&gt;Pipe and Transmission are &lt;strong&gt;one-way&lt;/strong&gt; (producer = client/Out, engine = server/In); no response over the same channel.&lt;/li&gt;
&lt;li&gt;The command bus is &lt;strong&gt;not&lt;/strong&gt; related to these channels despite the similar "command" wording — it is process-argument based and handled by Commandog.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TransmissionT&lt;/code&gt; managers are &lt;code&gt;null&lt;/code&gt; until constructed at runtime; &lt;code&gt;PipeT&lt;/code&gt; / &lt;code&gt;SignalT&lt;/code&gt; managers are static singletons created at type load.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="h-see-also"&gt;See also&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="./Commandog-Dispatcher"&gt;Commandog Dispatcher&lt;/a&gt; — the separate, process-launch command bus.&lt;/li&gt;
&lt;li&gt;&lt;a href="./Backgroundog-Service"&gt;Backgroundog Service&lt;/a&gt; — the data producer (FFT audio + system sensors).&lt;/li&gt;
&lt;li&gt;&lt;a href="./Create-Web-Architecture"&gt;Create Web Architecture&lt;/a&gt; — the JS-bridge consumer side.&lt;/li&gt;
&lt;li&gt;&lt;a href="./Create-Audio-API"&gt;Create Audio API&lt;/a&gt; — the &lt;code&gt;Audio&lt;/code&gt; payload for wallpaper authors.&lt;/li&gt;
&lt;li&gt;&lt;a href="./Create-System-API"&gt;Create System API&lt;/a&gt; — the system-status payload fields.&lt;/li&gt;
&lt;li&gt;&lt;a href="./Architecture-Overview"&gt;Architecture Overview&lt;/a&gt; — the multi-process model.&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Bayram Emekli</dc:creator><pubDate>Sat, 04 Jul 2026 04:15:30 -0000</pubDate><guid>https://sourceforge.net61e588d7e4df86ee3bb6bce76a1a8783dbd64236</guid></item></channel></rss>