From 09e5b59dfd552454c08f4798f0378deb15a39914 Mon Sep 17 00:00:00 2001 From: Zac Gaetano Date: Sat, 16 May 2026 11:23:19 -0400 Subject: [PATCH] fix: cold-start discovery + installer shortcuts + single-instance hardening MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three independent fixes bundled because all were chasing the same operator report: 'I just installed, launched from the shortcut, no participants.' 1) NdiDiscoveryService: poll immediately, then ramp from 200ms to the configured interval over the first 3 seconds. PeriodicTimer.WaitForNext- TickAsync waits the full interval before its first tick, so for a 500ms discovery interval the operator stared at 'no ndi sources yet' for half a second on every cold start. Force-poll up front (catches the runtime cache), then run a fast inner loop for ~3s while mDNS replies trickle in. Both loops share a try/finally so the NDI finder is always disposed. 2) MainViewModel.IsDiscovering: new boolean, true for 8s after engine start AS LONG AS no participants have arrived. MainWindow.xaml swaps the empty-state copy on this binding: IsDiscovering=true -> 'scanning for ndi sources...' (cyan dot) IsDiscovering=false -> 'no ndi sources visible -- is teams in a meeting?' + Refresh CTA The old copy ('no ndi sources yet -- open teams and start a meeting') was being shown immediately at launch even when discovery just hadn't run yet, making the app look broken. 3) App.xaml.cs: single-instance mutex moved from Local\ to Global\. On admin-user boxes with UAC disabled, launches from different parents (elevated File Explorer, non-elevated shell, etc.) can land in slightly different security contexts and a Local\ name can be invisible to the sibling. Global\ namespace closes that hole — both processes see the same mutex regardless of integrity. Belt-and-braces against future dual-instance file/port contention. 4) installer/Package.wxs: add a Desktop shortcut component (per-machine feature, HKCU keypath per ICE38/ICE43). Operators who can't find the Start Menu entry get the Desktop icon. Both shortcuts target the installed exe, NOT a stale path under publish/. --- installer/Package.wxs | 29 ++++++- src/TeamsISO.App/App.xaml.cs | 15 +++- src/TeamsISO.App/MainWindow.xaml | 60 ++++++++++---- src/TeamsISO.App/ViewModels/MainViewModel.cs | 43 ++++++++++ .../Discovery/NdiDiscoveryService.cs | 82 +++++++++++++++---- 5 files changed, 195 insertions(+), 34 deletions(-) diff --git a/installer/Package.wxs b/installer/Package.wxs index 79de7cd..46b3de9 100644 --- a/installer/Package.wxs +++ b/installer/Package.wxs @@ -40,6 +40,7 @@ + @@ -112,8 +113,9 @@ @@ -135,6 +137,29 @@ + + + + + + + + + + shape brief's empty-states section. + + Two visual flavors gated by IsDiscovering (the VM holds + it true for ~8s after engine start, false thereafter): + - IsDiscovering=true → "Scanning for NDI sources…" + (neutral; cold-start can take + 1-3s for mDNS to settle) + - IsDiscovering=false → the explanatory empty state + ("open teams and start a + meeting") + Refresh CTA + This stops operators from staring at a "broken-looking" + empty table during the first second of every launch. --> - -