Skip to content

Replace the bundled NirSoft tools with our own code (unblocks code signing) #91

Description

@lippdev

Why

Console Mode bundles two NirSoft tools inside the executable: MultiMonitorTool (displays) and SoundVolumeView (audio). They are free but closed source, and that blocks two things:

  • Code signing. The free SignPath Foundation program requires no proprietary code in the signed package. Unsigned releases show Windows SmartScreen's "unknown publisher" warning, which likely scares off more users than any bug. The repo side is ready (docs/CODE_SIGNING.md and the gated steps in release.yml, chore: prepare SignPath code signing (policy page, gated release steps) #90); this is the remaining blocker.
  • Antivirus false positives. The README already warns that antivirus may flag the bundled tools.

Replacing them with our own code (Win32 / Core Audio via P/Invoke) removes both problems and the dependency on nirsoft.net at build time.

Scope

Every call goes through two wrappers, so the migration can happen behind them:

Displays: MonitorService.InvokeMmt (~20 calls)

MultiMonitorTool command Used for Native replacement
/scomma + /HideInactiveMonitors 0 List monitors (active and inactive) QueryDisplayConfig (CCD) + EnumDisplayDevices
/SaveConfig, /LoadConfig Back up and restore the desk layout Store CCD paths/modes ourselves; SetDisplayConfig to restore
/enable, /disable, /SetMonitors Turn displays on/off, set positions SetDisplayConfig (CCD topology)
/SetPrimary Make the TV primary ChangeDisplaySettingsEx with CDS_SET_PRIMARY + repositioning
/TurnOn, /TurnOff Power displays (DDC/CI) SetVCPFeature (dxva2 Monitor Configuration API)
/MoveWindow Move a window to a monitor SetWindowPos

Native/CcdHelper.cs already talks to CCD (ExtendAll), so there is a starting point.

Audio: AudioService.InvokeSvv (~10 calls)

SoundVolumeView command Used for Native replacement
/scomma + /ShowDisabledDevices /ShowUnpluggedDevices List outputs IMMDeviceEnumerator (Core Audio)
/SetDefault … all Switch the default output (all roles) IPolicyConfig (undocumented COM, the same one NirSoft, EarTrumpet and AudioSwitcher use)
/Enable Enable a disabled output IPolicyConfig::SetEndpointVisibility
/GetPercent, /SetVolume, /Mute, /Unmute Session menu volume IAudioEndpointVolume

Plan

  1. Audio first. Smaller, well-known APIs, easy to verify by ear. One PR.
  2. Displays in steps: listing → enable/disable/primary → backup/restore → DDC/CI power. Keep the NirSoft path as a fallback behind a setting until each step is verified on real hardware, then remove it.
  3. Remove Get-NirSoftTools.ps1, the embedding in Publish-ConsoleMode.ps1 / EmbeddedFiles.cs, the MmtMissing / SvvMissing strings and the NirSoft section of THIRD_PARTY_NOTICES.md.
  4. Apply to SignPath.

Testing

None of this can be checked in CI; it needs Windows with real displays. Each PR adds its manual checks to docs/TESTING.md, covering at least: two desk monitors + a TV that starts off, disconnect vs. black-overlay vs. DDC/CI modes, restore after Big Picture / Playnite exit, and an HDMI audio output that only appears once the TV is on. Pure logic (config parsing, layout math) goes into linked files with unit tests.

Done when

  • The release build downloads and embeds no NirSoft binary.
  • The manual checklist passes on at least one multi-monitor + TV setup.
  • The next release can be submitted to SignPath.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpriority: highBlocks a release goal; do firstroadmapPlanned feature

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions