# EventSaver A rotating-image screensaver for shop-floor PCs. Idle bays show the slides managed in ShopDB, so a safety notice or a shift message reaches the floor without anyone walking to each machine. It is a small C# WinForms screensaver (`.scr`), not part of the ShopDB server. It is documented here because ShopDB serves its content and because a site adopting the fleet tools needs to know how it is configured. For how to deploy it at a new site, see [ADOPTING-AT-ANOTHER-SITE.md](ADOPTING-AT-ANOTHER-SITE.md). This page is what it is, how it decides what to show, and how to diagnose it. ## Two sources, one of them preferred EventSaver reads `EventSaver.ini` from the directory it lives in, **on every launch**. Retargeting it never needs a recompile. ```ini # HTTP mode: pull the playlist from ShopDB and cache it locally. url=https://shopdb.example.net/api/slides/feed?surface=shopfloor # Folder mode: used only when url is blank. SMB or local path. # folder=\\fileserver\shopfloor\tv interval=10 # seconds per image, unless a slide carries its own time shuffle=0 # 1 = random order, 0 = ordered fadems=600 # crossfade length in ms, reserved (v1 hard-cuts) ``` **HTTP mode is the one to use.** Slides are managed in ShopDB (Slides), the feed is public so the screensaver needs no credentials, and each PC caches what it fetched under its own `LocalApplicationData`. A bay that cannot reach the server keeps showing the last set it saw instead of going black - which matters, because the failure would otherwise be visible to the whole floor. **Folder mode** predates the server and stays as a fallback for a site with no ShopDB instance yet, or for content nobody wants in the database. > If `EventSaver.ini` is missing, or both `url` and `folder` are blank, the > binary falls back to a path compiled into `EventSaver.cs` - and that path > belongs to the site it was first built for. Ship the ini. A missing ini is not > a neutral default. ## What decides the running order | Situation | Behaviour | |---|---| | No `order.txt` | Every image shows, sorted by filename. Number them `001_`, `002_` to sequence. | | `shuffle=1` | Random order, ignored when a playlist is present. | | `order.txt` present | ONLY the listed files show, in the listed order, looped. | `order.txt` is the strict-sequence option and is the whole playlist - a file not listed does not appear. Per-slide duration is appended with a pipe: ``` # Lines starting with # or ; are ignored. 001_welcome.jpg 002_safety_week.jpg|15 003_quality_board.jpg ``` In HTTP mode you do not write `order.txt` by hand: ShopDB's feed carries the order and each slide's own seconds, and EventSaver writes the equivalent `order.txt` into its cache so the same playlist logic runs either way. A running screensaver rescans about every 30 seconds, so a slide change reaches the floor without touching any PC. ## Command-line switches Windows calls a screensaver with these, and EventSaver answers all three: | Switch | Meaning | |---|---| | `/s` | Show fullscreen. What Windows uses on idle. | | `/c` | Configuration. Reports the resolved source and cache directory, and points at the ini. | | `/p ` | Preview pane. Deliberately a no-op - it keeps the Settings dialog happy without drawing a thumbnail nobody looks at. | `EventSaver.scr /c` is the first diagnostic: it says which source it resolved and where it is caching, which answers most "why is it showing the wrong thing" questions immediately. ## Where it should and should not run A screensaver over a live display is a defect, not a feature. The reference fleet excludes: - **Kiosks and lobby displays**, which show a live dashboard. - **Metrology bays** - CMM, Genspect, Keyence, wax-trace - where an operator watches a measurement run. - **Bays that sleep**, where the screensaver never wins anyway. Targeting is per PC type in the GE-Enforce manifest, or by group assignment in Intune. Decide it deliberately: the cost of getting it wrong is a screensaver covering something someone needed to see. ## Building it No SDK required - it compiles with the in-box .NET Framework compiler on any Windows 10 or 11 machine: ``` C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe ^ /target:winexe /out:EventSaver.scr ^ /reference:System.dll,System.Drawing.dll,System.Windows.Forms.dll ^ EventSaver.cs ``` Ship `EventSaver.scr` and `EventSaver.ini` together. A `.scr` is an executable with a different extension, so it goes to `C:\Windows\System32\`. ## Diagnosing it | Symptom | Cause to check first | |---|---| | Blank screen, no images | Source unreachable and cache empty. Run `/c` and open the `url` in a browser on that PC. | | Old slides only | Feed reachable at first run, not since. The cache is doing its job; fix the network path. | | Wrong content | Pointing at another surface, or another site's server. `/c` reports which. | | Local ini edits revert | Correct behaviour if the config is enforced by hash. Edit the copy on the share and update its `DetectionValue`. | | Screensaver never starts | Per-user setting missing. Check `HKCU:\Control Panel\Desktop` for `SCRNSAVE.EXE`, `ScreenSaveActive` and `ScreenSaveTimeOut`. | The feed is a plain public endpoint, so it can always be checked from the PC itself: ``` https://shopdb.example.net/api/slides/feed?surface=shopfloor ``` An empty `slides` array means no slides have been uploaded for that surface - the PC is configured correctly and there is nothing to show.