Keeps any window's content out of screenshots, screen recordings, most
screen-share tools, and most remote-control/remote-support viewers — while
it still displays normally on your own screen. It ships with automatic
detection for Citrix Workspace app and AVD ("Windows App") session
windows specifically, since that's the case it was originally built for —
connecting to a corporate virtual desktop from a personal device, where a
compromised or screen-shared device could otherwise leak what's on screen
— but --manual mode works against any visible window, not just
Citrix/AVD.
For how it actually works under the hood (the Windows API involved, why it's a tray app with an HKCU Run key and not a service or a scheduled task, how auto-detection works, the compliance/EPA angle, and honest limitations), see ARCHITECTURE.md.
- Run
ViewGuardSetup.exe. No admin rights, no UAC prompt — it installs to your own user profile only. - On the finish page, make sure "Protect my Citrix/AVD session now
(automatic)" is checked (it's checked by default), then click
Finish. With your Citrix or AVD session open, this launches
vgwizard.exefor you and it auto-detects + protects the session window — no selection to make. A console window will pop up showing what it detected and did; it waits for you to press Enter before closing, so it won't just flash by unread. (If you ever click Finish with that box unchecked, nothing gets set up — just runvgwizard.exefrom%LOCALAPPDATA%\Programs\ViewGuardafterward to finish the job.) - Done. A ViewGuard icon appears in your system tray — that's
vgtray.exe, and it's what keeps protection running. Right-click it any time to turn protection on/off, re-detect after a client update, open the install folder, or exit. It relaunches automatically every time you log in.
If your antivirus quarantines any of these files (expected — see
"Things to expect, not bugs" below), add a folder exclusion for both
%LOCALAPPDATA%\Programs\ViewGuard (where the installer puts things) and
%LOCALAPPDATA%\ViewGuard (where vgwizard.exe copies the files
vgtray.exe actually runs) before restoring from quarantine and
re-running — otherwise whichever folder isn't excluded will just get
re-flagged immediately.
That's the whole workflow for most people. Everything below is for when you want more control, need to troubleshoot, or are setting this up without the installer.
| File | What it is |
|---|---|
ViewGuardSetup.exe |
Installer — the easiest way to get set up |
vgwizard.exe |
Setup tool: auto-detects a Citrix/AVD session (or --manual for any app) and hands off to the tray app |
vgtray.exe |
Runs at logon, shows the tray icon, and keeps protection active — right-click to toggle it |
vgagent32.exe / vgagent64.exe |
Watcher vgtray.exe runs in the background, which injects protection into matching processes |
vghook32.dll / vghook64.dll |
The actual protection, loaded into the target process |
common.h, hook.cpp, agent.cpp, wizard.cpp, tray.cpp |
Full source for everything above |
installer.nsi |
Source for the installer, buildable with NSIS |
ARCHITECTURE.md |
How it works internally |
The prebuilt .exe/.dll files were cross-compiled here with MinGW-w64
purely to confirm they build cleanly with zero warnings — treat them as a
convenience, not something to blindly trust. Full source is included; see
"Building it yourself" in ARCHITECTURE.md if you'd rather build from
source yourself.
Run vgwizard.exe with no arguments (this is exactly what the installer's
finish page does):
vgwizard.exe
It detects any currently visible window belonging to a known Citrix/AVD
client process, writes that as the protected list, registers vgtray.exe
to launch at your next logon, and starts it immediately. No prompts. If it
doesn't find anything, it tells you why and what to try next (open your
session first, or see known_names.txt below) — you don't need to re-run
vgwizard.exe again after a client update either, since the tray icon has
its own Re-detect now option (see below).
Once set up, look for the ViewGuard icon in your system tray. Right-click it for:
- Protection Enabled — a checkable toggle. Unchecking it instantly reveals any window it was hiding (usually within under a second) without stopping the background watcher entirely; re-checking it hides them again. This is real-time — it affects windows that are already hidden, not just future ones.
- Re-detect now — re-scans for known Citrix/AVD windows and updates
what's protected, without needing to re-run
vgwizard.exeor reinstall. Useful after a Citrix/Windows App client update changes which process owns the session window. - Open install folder — opens
%LOCALAPPDATA%\ViewGuardin Explorer. - Exit (stop protection) — fully stops everything and removes the tray
icon for this session. It comes back at your next logon (the Run key
entry isn't removed by Exit — only
--uninstallremoves that).
Citrix/Microsoft client process names change across versions and can be
unrecognizable (this project already ran into that: the real process
turned out to be Citrix.DesktopViewer.App.exe, not the classic
CDViewer.exe). If detection comes up empty and you know the process
name, add it without recompiling anything — drop a known_names.txt file
next to vgwizard.exe and next to vgtray.exe (%LOCALAPPDATA%\ViewGuard,
since that's where vgtray.exe actually runs from), one exe name per
line:
# comments and blank lines are ignored
SomeNewCitrixClient.exe
If the app you want to protect isn't Citrix/AVD, or you'd rather pick by hand:
vgwizard.exe --manual
Lists every visible window, lets you choose one or more by number, and
asks whether to also cover child/helper processes. Same hand-off to
vgtray.exe afterward as the automatic path.
vgwizard.exe --uninstall
Or use Apps & Features / the Start Menu shortcut if you installed via
ViewGuardSetup.exe. Stops vgtray.exe, removes the HKCU Run key
entry, and deletes everything under %LOCALAPPDATA%\ViewGuard.
For scripting or troubleshooting, vgagent32.exe/vgagent64.exe can be run
directly:
vgagent64.exe --list :: show every visible window + owning exe/pid
vgagent64.exe [--tree] vghook64.dll <exe_name...> :: watch and inject
Use --list first if you're not sure which process actually owns your
session's visible window — see ARCHITECTURE.md for why that isn't always
obvious. Note that a window injected this way ignores the tray's
Enable/Disable toggle only if vgtray.exe was never started (the
vghook DLL defaults to "protect" when it can't find the tray's on/off
signal at all) — running alongside the tray, it's controlled by it like
everything else.
- Run the wizard, confirm the tray icon appears and its tooltip reads "Protection ON."
- Take a local screenshot (Print Screen / Snipping Tool) with the session window visible — that region should come back blank, including when it's just in the background of an unrelated screenshot.
- Right-click the tray icon and uncheck Protection Enabled — the window's content should reappear in a screenshot within about a second. Re-check it and confirm it blanks out again.
- Optionally, connect to the same machine remotely (e.g. from your phone) and confirm the session window is blank there too, while the rest of the desktop shows normally.
If step 2 works but step 4 doesn't, your remote-viewing tool isn't reading the desktop through the standard compositor-backed capture path — see ARCHITECTURE.md's "Scope, honestly" section.
- Antivirus/EDR will likely flag this — DLL injection is a well-known pattern most AV engines flag heuristically regardless of intent. If Defender or your AV quarantines something here, that's expected, not a sign it's broken. (See ARCHITECTURE.md for why this technique needs injection at all, and why persistence is a Run key rather than a Scheduled Task.)
- Automatic detection only protects processes on the known-names list. If nothing visible matches, it says so and changes nothing — it never guesses.
- Re-running
vgwizard.exe(auto or--manual), or using Re-detect now from the tray, fully replaces the previous protected list — it doesn't merge with a prior run. - The exclusion applies to everyone viewing the composited desktop, including you, if you remote into your own machine to check it. A blank window when you remote in is confirmation it's working, not a bug.
- Exit vs. Disable: unchecking "Protection Enabled" pauses hiding but
keeps the watcher running; Exit stops everything (including the
watcher) until your next logon or until you manually run
vgtray.exeorvgwizard.exeagain.
This blocks the standard OS compositor-backed capture path — Print Screen, Snipping Tool, most screen recorders/share tools, and most remote-control software in typical configurations. It does not stop physical photography of the monitor, and it won't stop a capture method that deliberately bypasses the compositor. It's a real mitigation, not a guarantee. Full details, plus how this interacts with org-level compliance checks (Citrix Gateway EPA), are in ARCHITECTURE.md.