A small Windows tray-less WPF utility that switches your monitor's input source (HDMI 1, DisplayPort 2, USB-C, …) with a global hotkey — or from the command line — instead of digging through the monitor's on-screen menu with the joystick nub on the back.
It talks to the display over DDC/CI, the side-channel that rides along the video cable. Two transports are supported:
| Transport | How | Use it when |
|---|---|---|
dxva2 (Windows SetVCPFeature) |
Standard MCCS write to VCP register 0x60 |
Your monitor is well-behaved and follows the spec |
| NVAPI raw I2C | Writes the DDC/CI packet directly on the I2C bus of an NVIDIA GPU | Your monitor ignores standard writes (notably LG UltraGear — see below) |
Most monitors accept a plain SetVCPFeature(0x60, <input code>) and switch. Some don't. LG UltraGear panels (confirmed on the 27GN800) silently ignore VCP 0x60 entirely. Their input select lives on a non-standard register 0xF4, reachable only through the 0x50 service side-channel — an I2C source address that the Windows dxva2 API will not emit.
So NvApi.cs builds the DDC/CI packet by hand (length byte, Set-VCP opcode, register, hi/lo value, XOR checksum) and pushes it through NvAPI_I2CWrite on every connected display of every NVIDIA GPU. The LG acts on 0xF4; other monitors just ignore a VCP code they don't know.
This is why the app ships with LG-friendly defaults. If you have a normal monitor, un-tick the NVIDIA box and you're on the standard path.
- Windows 10/11 (x64)
- .NET 10 SDK to build (the published binary is self-contained — no runtime install needed)
- DDC/CI must be enabled in the monitor's OSD. Many monitors ship with it off, and nothing will work until you turn it on.
- NVIDIA GPU + driver, only if you use the NVAPI transport (
nvapi64.dllcomes with the driver)
git clone https://github.com/Lunat1q/MonitorInputWizzard.git
cd MonitorInputWizzard
dotnet run
Single-file release build:
dotnet publish -c Release
The .exe lands in bin/Release/net10.0-windows/win-x64/publish/.
The window is a list of input presets. Each preset is a name, a VCP code, and an optional global hotkey.
- Pick your transport. Leave Use NVIDIA I2C ticked for an LG UltraGear; un-tick it for a standard monitor (which enables the monitor picker below).
- Set the input register.
0x60is the MCCS standard.0xF4is LG UltraGear. - Find your input codes. Switch the monitor to an input by hand, then hit Read — it prints the register's current value, which is that input's code. Repeat per input, typing each value into the preset's Code box.
- Bind a hotkey. Click a preset's hotkey button, press the combo.
Escclears it. Hotkeys are system-wide (registered viaRegisterHotKey, with auto-repeat suppressed) and fire even when the window isn't focused. - Save. Settings persist to
%AppData%\MonitorInputWizzard\settings.json.
Test dims the selected monitor's brightness for ~1 second and restores it. If the screen visibly dims, DDC/CI writes are reaching the panel — so any input-switch failure is a wrong register or a wrong code, not a broken connection. (dxva2 mode only.)
Tuned for LG UltraGear — register 0xF4, NVAPI on, source address 0x50:
| Input | Code |
|---|---|
| DisplayPort 1 | 0xD0 |
| DisplayPort 2 | 0xD1 |
| HDMI 1 | 0x90 |
| HDMI 2 | 0x91 |
| USB-C | 0xD2 |
For a standard monitor on register 0x60, the usual MCCS codes are 0x0F (DisplayPort 1), 0x10 (DisplayPort 2), 0x11 (HDMI 1), 0x12 (HDMI 2).
Passing an input name switches to it and exits immediately — no window:
MonitorInputWizzard.exe "HDMI 1"
MonitorInputWizzard.exe HDMI1 # spaces and case are ignored
MonitorInputWizzard.exe --switch "USB-C"
It reuses the saved settings, so configure once in the GUI, then wire the .exe into a Stream Deck button, an AutoHotkey script, or a shortcut.
Nothing happens. Check DDC/CI is on in the monitor's OSD. Then hit Test — if brightness doesn't move, DDC/CI isn't getting through at all (bad/adapter cable, DDC/CI off, or a KVM/dock in the path eating the channel).
Test dims fine, but the input won't switch. Wrong register or wrong code. Use Read on each input to harvest the real codes. If 0x60 reads back as unsupported, try 0xF4 with the NVAPI box ticked.
"No DDC/CI monitors found." Windows sees no monitor exposing a physical DDC/CI handle. Common with DisplayLink/USB display adapters and some laptop internal panels — those simply can't be driven this way.
Hotkey says it's already in use. Another app grabbed that combo first. Pick a different one.
| File | What it does |
|---|---|
| MonitorController.cs | Enumerates physical monitors, reads/writes VCP features via dxva2.dll |
| NvApi.cs | Hand-rolled DDC/CI packets over NVAPI raw I2C, for monitors dxva2 can't reach |
| HotkeyManager.cs | System-wide hotkeys via RegisterHotKey + a WndProc hook |
| Settings.cs | Presets and transport config, persisted as JSON in %AppData% |
| MainWindow.xaml.cs | The UI: preset list, hotkey capture, Read/Test diagnostics |
| App.xaml.cs | Startup; headless command-line switch path |
- The NVAPI path broadcasts the write to every connected display on every NVIDIA GPU rather than targeting one. Harmless in practice — monitors ignore VCP codes they don't implement — but if it ever bites, per-display targeting by EDID match is the fix.
- NVAPI transport is NVIDIA-only. AMD/Intel users on a monitor that needs the side-channel are out of luck for now.