Skip to content

Component: MouseHookPipe

Canonical source: SmrtApps/CSApps/MouseHookPipe/README.md (mirrored below)


MouseHookPipe — global mouse hook broadcaster

MouseHookPipe installs a global low-level mouse hook, mirrors selected events over an internal named pipe, and keeps the hook healthy through idle detection, power transitions, and self-healing timers. It runs headless alongside Supervisor and other CSApps.

Overview and responsibilities

  • Owns the low-level global hook thread and message pump.
  • Publishes best-effort click telemetry over a named pipe for local consumers.
  • Maintains hook health across idle/suspend/resume via self-healing routines.

Highlights

  • Enforces SmrtHub logging at startup (mouse-hook-pipe slug) and keeps the process single-purpose.
  • Dedicated hook thread owns SetWindowsHookEx, UnhookWindowsHookEx, and a Win32 message pump to stay compliant with owner-thread requirements.
  • Named pipe client (smrthub_mousehook) publishes click events with ISO-8601 timestamps for downstream consumers.
  • Self-healing routines (heartbeat, mouse silence checks, idle detection) rehook when activity stalls while avoiding thrash via debounce timers.
  • Every rehook/unhook request is reason-tagged and emits queue delay, reinstall duration, and first-event latency metrics for auditing the hook’s resilience.
  • Reacts to Windows power/session events: unhooks on suspend/lock and rehooks on resume/unlock.
  • Idle detection uses GetLastInputInfo so the component can log when users go idle/active for telemetry parity.

Runtime flow

  • Program.Main() configures logging via ConfigurationBuilder().AddSmrtHubLoggingDefaults() before any Win32 calls.
  • A HookThread instance spins up a background thread, captures its thread ID, installs the low-level hook, and handles custom control messages (WM_APP_REHOOK, WM_APP_UNHOOK).
  • The static hook callback stamps _lastMouseEvent, enqueues a pipe write on a thread pool worker, and always forwards to CallNextHookEx.
  • Timers:
    • Heartbeat (60s): logs that the process and hook ID are alive.
    • Mouse silence (120s): if no events but the system is not idle, post a rehook.
    • Idle monitor (1s): logs idle/active transitions and rehooks on active resume.
    • Chain refresh (10 min, opt-in): disabled by default; can rehook proactively when enabled.
  • Power and session change handlers marshal rehook/unhook requests onto the hook thread to keep the chain in good shape during suspend/resume cycles.
  • Process shutdown: AppDomain.ProcessExit disposes the hook thread to post WM_QUIT and allow the owner thread to cleanly uninstall the hook.

IPC contract

  • Named pipe: \\.\pipe\smrthub_mousehook (client stream opened from within the callback).
  • Message format: single text line click <UTC_ISO8601> per left-click (WM_LBUTTONDOWN).
  • Pipe write timeout: 100 ms; failures are logged at Error (no retries today).
  • Consumers should treat the pipe as best-effort telemetry (no dedupe or ordering guarantees beyond FIFO).
  • Primary consumer today is python_core.smrtdetect.localsource. That listener connects, reads exactly one message, and expects the C# side to close the client handle immediately. If the hook ever stops disposing its NamedPipeClientStream (regression we fixed in 2025-08), Localsource remains stuck on the existing handle and new mouse events never arrive. Keep the connect → write → dispose handshake intact on both sides.

Dependencies and integrations

  • Primary consumer: python_core.smrtdetect.localsource (local-only telemetry input)
  • Logging: SmrtHub.Logging (slug mouse-hook-pipe)
  • Config/path resolution: Smrt.Config

Self-healing notes

  • _selfHealAttempts counts mouse-silence-triggered rehooks for observability; idle periods do not count.
  • Recovery telemetry logs (1) how long a rehook waited in the queue, (2) how long reinstalling the hook took, and (3) how quickly the first mouse event arrived afterward, making it easy to prove hook health over time.
  • Rehook debounce (RehookDebounce = 2s) prevents rapid reattachment loops when multiple triggers fire together.
  • Warnings log when control messages arrive before the hook thread has published its owner thread ID (useful during early startup diagnostics).

Configuration & logging

  • Config roots resolve through Smrt.Config helpers; component state lives under %AppData%/SmrtHub/Config/mouse-hook-pipe/.
  • Logs emit to %LocalAppData%/SmrtHub/Logs/mouse-hook-pipe/ as text + JSON; HTML exports use the standard logger extension (see README.Files/Reference-Guides/SmrtHub.Logging.README.md).
  • Operational data policies (slugs, retention, and bundle behavior) follow README.Files/System/Policies/SmrtHub-Operational-Data-Policy-v1.0.README.md.

Support Bundle

  • MouseHookPipe logs should be collected via Support Bundle exports using the canonical log folder for mouse-hook-pipe.
  • Prefer a Support Bundle when diagnosing hook instability across power/session transitions.

Files

  • Program.cs — Main entry point, timers, hook callback, hook-thread orchestration, power/session handlers.
  • NativeMethods.cs — Minimal Win32 shims (GetMessage, PostThreadMessage, GetCurrentThreadId).

Validation checklist

  • Launch MouseHookPipe and verify console/log heartbeat entries every 60 seconds.
  • Click while active: pipe consumers should receive click messages; logs show Sent mouse event entries.
  • Stay idle for >2 minutes, then move the mouse: logs show idle entry/exit and a rehook event.
  • Suspend and resume the machine: hook uninstalls on suspend and reinstalls on resume (check info logs).

Build & deploy

  • Build script: SmrtApps/CSApps/MouseHookPipe/Build-MouseHookPipe.ps1 (wraps central build automation).
  • Staging: Apps/<Configuration>/<RID>/MouseHookPipe/ with RID locked to win-x64 per platform policy.

Roadmap

  • Pipe payload currently encodes only left-click events; extend format once we add additional gestures.
  • Consider elevating _selfHealAttempts metrics to Supervisor so repeated failures can prompt restarts.
  • README.Files/Reference-Guides/SmrtHub.Logging.README.md
  • README.Files/System/Policies/SmrtHub-Operational-Data-Policy-v1.0.README.md

Generated output

  • bin/ and obj/ hold the build artifacts generated by the .NET SDK. They are excluded from recursive README coverage per the documentation policy and should remain untouched in source control.