Skip to content
Mikhail Deynekin edited this page Oct 16, 2026 · 7 revisions

TrayIconGuard

Windows 11 Windows 10 Native C++17 Zero install dependencies License

TrayIconGuard keeps every notification-area (system tray) icon visible on Windows 10 1703+, Windows 11 and Windows Server 2019+. It writes IsPromoted=1 into HKCU\Control Panel\NotifyIconSettings\{id} — the same per-icon store the Windows Settings toggles use — and runs a watcher that reconciles the store whenever Explorer touches it, because Explorer resets IsPromoted to 0 each time an application (re)registers a tray icon. The program is a single statically linked native Win32 C++17 executable (measured 1,052,672 bytes at the studied commit) that imports only Windows system DLLs: no .NET, no runtimes, no redistributables.

The project evolved through three generations in one repository: the v4–v6 script era (BAT / PowerShell / .reg), v7 “Phoenix” (C# WPF plus PowerShell and BAT editions), and v8 “Aurora” — the native rewrite this wiki documents. The current release is v8.6.3 (2026-10-16): feed, tag, src/core/version.h and every banner agree since v8.4.1, and the CI release job pins the feed from the bytes the release actually serves. Pages that describe the 8.4.0-era audit keep that framing and say so — the drift they document is history (see Changelog and Versioning).

Important

TrayIconGuard never requires administrator rights and never writes outside HKCU and the user's own AppData folders. Conversely, there is no all-users mode: per-icon promotion has no Group Policy equivalent on Windows, so every account on a machine needs its own configuration. The watcher caveat tracked in The Guard Watcher is now history: in 8.3.0 – 8.6.2 the guard thread waited only on its stop event, so with the default pollMs: 0 the armed registry notification was never observed and the loop never woke by itself. Fixed in 8.6.3 (WaitForMultipleObjects over stop/registry/wake) and verified against the released binary: an icon whose IsPromoted is forced to 0 is promoted back within ~2.5 s.


Contents


Key features

  • Correct mechanics — per-icon promotion through NotifyIconSettings\IsPromoted, the exact store behind the Windows Settings toggles (src/core/trayicons.cpp:14).
  • Watcher — RegNotifyChangeKeyValue on the store subtree with a configurable debounce (default 400 ms) and optional polling fallback; visibility modes full, custom and compact (src/core/guard.cpp).
  • Per-icon control — promote/hide individual icons, wildcard exclusions (onedrive.exe, *teams*), search, filters, extracted icons and friendly names, drag-reorder (src/ui/pages/icons.cpp).
  • Single dependency-free executable — static mingw/MSVC build, 16 imported DLLs, all Windows system libraries (verified with objdump -p).
  • Fluent custom-drawn GUI — seven pages, Light/Dark/System themes, eight accent presets or Windows colorization, Per-Monitor-V2 DPI, dark title bar and rounded corners on Windows 11 (src/ui/).
  • Localization — 30 locales with per-string English fallback; Russian complete, eight locales with core coverage, the rest essential subsets (docs/I18N.md).
  • Safety nets — schema-8 JSON snapshots with automatic backup before bulk changes, 30-snapshot retention, 14-day rotating logs, atomic settings writes (src/core/backup.cpp, src/core/log.cpp, src/util/fs.cpp).
  • Ops-friendly CLI — 18 commands, stable exit codes 0/1/2/3, machine-readable --status --json, headless --watch (docs/CLI.md).
  • Embedded installer — first-run wizard (folder, autostart, shortcuts) or portable mode; Apps & Features entry; --uninstall removes everything (src/core/installer.cpp).
  • Self-updater — opt-in HTTPS feed with mandatory SHA-256 pinning, rename-chain self-replace and relaunch (src/core/update.cpp, Updater_SKILL.MD).
  • Respectful defaults — HKCU only, no telemetry, opt-in update checks, close-to-tray, single instance (docs/PRIVACY.md).

Quick start — five minutes

# 1. get it (release asset; verify against SHA256SUMS in the release)
curl -L -o TrayIconGuard.exe https://github.com/paulmann/windows-show-all-tray-icons/releases/latest/download/TrayIconGuard.exe

# 2. unblock once (downloaded files carry Mark-of-the-Web)
Unblock-File .\TrayIconGuard.exe

# 3. run it — first run opens the setup wizard; choose Install or portable
.\TrayIconGuard.exe

# 4. headless one-shot, e.g. from a logon script
.\TrayIconGuard.exe --promote-all

# 5. machine-readable state for monitoring
.\TrayIconGuard.exe --status --json

Expected output of the last command on a supported Windows (fields verified against src/core/cli.cpp:66-88; values are illustrative):

{
  "app": "TrayIconGuard 8.0.0",
  "os": "Windows 11 Professional (build 26100)",
  "build": 26100,
  "storeSupported": true,
  "total": 14,
  "promoted": 14,
  "hidden": 0,
  "excluded": 1,
  "enableAutoTray": 0,
  "hideScaPolicies": 0,
  "autostart": true,
  "icons": [ { "id": "{…}", "exe": "C:\\…\\app.exe", "name": "App", "promoted": true, "excluded": false } ]
}

Note

The sample above was captured from an 8.3.0/8.4.0 build, where this field was a hardcoded 8.0.0 banner (src/core/cli.cpp). Since v8.4.1 every banner is generated from src/core/version.h, so on 8.6.3 the same field reports TrayIconGuard 8.6.3. The drift itself is catalogued in Changelog and Versioning.

How it is put together

flowchart LR
    subgraph UI["UI thread"]
        MW["main window shell<br/>7 pages, tray icon"]
    end
    subgraph ENG["engine (src/core)"]
        ST["store: NotifyIconSettings"]
        GD["guard worker:<br/>arm - wait - debounce - pass"]
        BK["backups / settings / log"]
        UP["updater: WinHTTP + SHA-256"]
    end
    EX["Explorer"] -->|"creates subkeys,<br/>resets IsPromoted"| ST
    GD -->|"IsPromoted = 1"| ST
    GD -->|"PostMessage events"| MW
    MW -->|"commands"| GD
    UP -->|"confirmed update"| MW
Loading

Full detail, including the thread model and IPC contracts, lives in Architecture; the registry mechanics and the decay problem are explained in How Tray Visibility Works.

Requirements

Requirement Detail
OS Windows 10 1703+ (build 15063+), Windows 11, Server 2019/2022/2025, x64
Runtimes none — imports only OS-provided DLLs (measured: 16, all system)
Rights standard user; HKCU writes only; no UAC prompt
Disk ~1 MB for the executable; AppData folders for settings/logs/snapshots
Pre-1703 builds store absent: Dashboard reports the limitation, store commands exit 2

Wiki navigation

Page What it covers
Getting Started download, verify, first run, portable vs installed, first five minutes
Features Overview measured feature matrix, including honest divergences
Comparison with Alternatives the problem space and the October 2026 tool landscape
Installation and Deployment wizard, scripts, MSIX, autostart, headless deployment, SmartScreen
Configuration Reference every settings.json key and registry location, with defaults
Command-Line Interface 18 commands with exact outputs and exit codes
How Tray Visibility Works the store, the decay problem, legacy switches, danger zones
Legacy Script Editions v6/v7 BAT, PowerShell and .reg history with working examples
The Guard Watcher watcher design, modes, timing knobs, known defect and fix
GUI Pages Guide the seven pages, tray menu, keyboard map, --ui-test
Backups and Snapshots snapshot anatomy, auto-backup, restore/export/delete
Localization and Themes 30 locales, themes, accents, design tokens
Self-Updater Guide feed contract, publication checklist, failure matrix
Security and Privacy threat model, trust boundaries, residual risks
Troubleshooting every observed error string and exit code, with fixes
Architecture component map, threads, IPC, data locations
Building from Source cross/native/MSVC recipes, CI gates
Changelog and Versioning v4→v8 timeline and the version-string drift record
FAQ short answers to recurring questions
Glossary canonical terminology

Project facts

Repository https://github.com/paulmann/windows-show-all-tray-icons
Audit baseline (this wiki's pages) commit 124e849
Current release v8.6.3 (2026-10-16)
Tags on the remote v6.2 · v7.0.3 · v8.6.3 (the 8.3.0/8.4.0/8.4.1/8.6.0/8.6.1/8.6.2 releases and tags were removed)
Update feed version 8.6.3 (update/stable.json, pinned by CI from the served bytes)
Source version constants 8.6.3 (src/core/version.h)
License PolyForm Noncommercial 1.0.0
Author Mikhail Deynekin — icons@Deynekin.com · https://Deynekin.com
Executable size (measured) 1,052,672 B (8.3.0 HEAD build) · 1,105,920 B (release 8.6.3)

See also

Clone this wiki locally