A web-based tool for managing Android devices, CCTV cameras, Jellyfin media server, and system utilities from one place.
Control Menu replaces a collection of PowerShell scripts with a cross-platform web UI. It manages:
- Android Devices — Connect, reboot, toggle power/screensaver, manage ADB settings, and screen mirror Google TVs and Android phones via ws-scrcpy-web. mDNS-based network discovery with one-click Add for unregistered devices and auto-classification (phone / tablet / TV / watch) via an ADB shell probe.
- Android Power Tools — ws-scrcpy-web's full home page embedded in an iframe at
/android-power-tools. Direct access to the power-user workflows not duplicated in the Devices module: shell (xterm), file browser, stream configuration, network scan + manual-add, and dependency updater. Theme syncs bidirectionally with the iframe viapostMessage(requires ws-scrcpy-web v0.1.24-beta.5+). - Cameras — View LTS/Hikvision CCTV cameras via go2rtc RTSP-to-browser streaming. Configurable camera count with encrypted credential storage. go2rtc is auto-installed and updated via the dependency manager.
- Jellyfin Media Server — Database date updates, cast & crew image refresh (background worker with resume support), Docker container management, automated backups with configurable retention
- Utilities — Image-to-ICO icon conversion (PNG, JPG, BMP, GIF, WEBP, TIFF via SkiaSharp) with native file picker, Windows Zone.Identifier file unblocker
- Dependency Management — Auto-installs and updates ADB, scrcpy, Node.js, sqlite3, and go2rtc to a self-contained
dependencies/folder. Configurable install paths per tool. Version checks via GitHub API and direct URL scraping. Services are automatically stopped before binary updates and restarted after.
- Modular architecture —
IToolModuleinterface with auto-discovery via reflection - First-run wizard — 7 steps: Welcome, Android Devices, Cameras, Jellyfin, Email, Dependencies, Done
- Dark/light theme — OAO grey palette with two-state toggle
- Cross-platform —
CommandExecutorstrategy pattern abstracts Windows vs Linux commands - Encrypted secrets — ASP.NET Data Protection API for API keys and passwords
- Background jobs — Long-running tasks with progress tracking, cancellation, and resume
- Self-contained dependencies — Bundled tools folder resolved through an
IDependencyPathResolverboundary (no systemPATHresolution for bundled binaries); install/update buttons in UI; services auto-stop/restart during updates - Email notifications — Configurable SMTP with dedicated From address for provider authorization
- File System Access API — Native OS file picker for icon conversion in Chrome/Edge
- .NET 9 SDK
- Node.js (for ws-scrcpy-web screen mirroring, optional — auto-installable)
- ADB / Platform Tools (optional — auto-installable)
- Docker (for Jellyfin management)
cd src/ControlMenu
dotnet runOpen http://localhost:5159 in your browser. The first-run wizard will guide you through setup.
dotnet test143+ tests covering services, modules, and integrations.
src/ControlMenu/
Components/ # Blazor pages and layouts
Layout/ # MainLayout, Sidebar, TopBar
Pages/ # Home, Settings, Setup Wizard
Shared/ # ScrcpyMirror component
Data/ # EF Core entities, enums, migrations
Modules/ # Pluggable tool modules
AndroidDevices/ # ADB service, Google TV & Android Phone dashboards
AndroidPowerTools/ # ws-scrcpy-web home page iframe (shell, files, configure)
Cameras/ # CCTV camera streaming via go2rtc
Jellyfin/ # Docker ops, DB updates, Cast/Crew worker
Utilities/ # Icon converter, File unblocker
Services/ # Core services (config, secrets, jobs, dependencies, email)
wwwroot/ # Static assets, CSS, theme, JS interop
tests/ControlMenu.Tests/
| Decision | Rationale |
|---|---|
| Blazor Server (not WASM) | Needs direct access to ADB, Docker, filesystem |
IDbContextFactory |
Prevents stale EF change tracker in long-lived Blazor circuits |
IServiceScopeFactory for background work |
Workers outlive the Blazor circuit that started them |
| SQLite | Single-file DB, no external database server needed |
| SkiaSharp for images | Cross-platform replacement for System.Drawing.Common |
| ws-scrcpy-web via iframe | Screen mirroring without native scrcpy binary dependency |
| File System Access API | Native OS file dialogs for icon converter (Chrome/Edge) |
| Self-contained dependencies | 5 auto-managed tools in dependencies/; 2 external (Docker, ws-scrcpy-web) |
Control Menu manages two types of dependencies:
Auto-installable (downloaded to dependencies/ folder):
| Tool | Source | Purpose |
|---|---|---|
| ADB | Google (DirectUrl) | Android device management |
| scrcpy | GitHub (Genymobile/scrcpy) | Screen mirroring server binary |
| Node.js | nodejs.org (DirectUrl) | ws-scrcpy-web runtime |
| sqlite3 | sqlite.org (DirectUrl) | Jellyfin database operations |
| go2rtc | GitHub (AlexxIT/go2rtc) | RTSP-to-browser camera streaming |
External (installed separately):
| Tool | Purpose |
|---|---|
| Docker | Jellyfin container management |
| ws-scrcpy-web | Browser-based screen mirroring |
Install paths are configurable per-tool in Settings > Dependencies.
Modules implement IToolModule and are discovered at startup:
public interface IToolModule
{
string Id { get; }
string DisplayName { get; }
string Icon { get; }
int SortOrder { get; }
IEnumerable<ModuleDependency> Dependencies { get; }
IEnumerable<ConfigRequirement> ConfigRequirements { get; }
IEnumerable<NavEntry> GetNavEntries();
IEnumerable<BackgroundJobDefinition> GetBackgroundJobs();
}Modules must have parameterless constructors for auto-discovery.
GPL-3.0-only. See LICENSE for full terms. By contributing you agree your contributions are licensed under the same terms — see CONTRIBUTING.md for details.
For vulnerability reports, see SECURITY.md. Do not open public issues for security problems.