Skip to content

Give the hook daemon a Windows version resource - #537

Merged
mgth merged 1 commit into
masterfrom
hook-version-resource
Aug 3, 2026
Merged

Give the hook daemon a Windows version resource#537
mgth merged 1 commit into
masterfrom
hook-version-resource

Conversation

@mgth

@mgth mgth commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Groundwork for #535 / #536, but a fix in its own right.

The gap

rustc emits no VERSIONINFO resource and nothing in this crate supplied one, so LittleBigMouse.Hook.exe has been shipping with no product name, no version and no copyright at all — installed right next to a UI exe that carries all three. It is visible in the file properties dialog and in Task Manager.

It also matters for signing: a SignPath artifact configuration can constrain product and version metadata, and there is nothing here for it to match against.

What it does

build.rs stamps the resource. The version comes from LBM_VERSION when CI sets it from the tag, otherwise from Directory.Build.props.

Reading the props file is the point of the change. It is already documented as the single source of truth for the managed version, and without it this crate would keep announcing its own 0.1.0 from inside a 5.6.0 installer — exactly the drift a signing policy would reject, discovered at release time.

Two details worth a look:

  • Parsed with roxmltree, not substring-matched. Directory.Build.props names <Version> inside its own comment several lines above the real element, so find("<Version>") returns the comment body. My first attempt did exactly that and produced FILEVERSION 0, 0, 0, 0 with a paragraph of prose as the FileVersion string. roxmltree is already a dependency of this crate.
  • winresource is in plain [build-dependencies], not under cfg(windows). Build dependencies resolve against the host, so gating it that way silently breaks a Linux host cross-compiling to Windows. build.rs returns early on CARGO_CFG_TARGET_OS instead; the Linux build is untouched.

String fields keep the full version (5.7.0-beta.1); the fixed part of VERSIONINFO is four u16s, so the numeric fields carry the same version with the pre-release suffix dropped.

Verification

Cross-compiled to x86_64-pc-windows-gnu and read back out of the PE:

Build FILEVERSION ProductName
default (from Directory.Build.props) 5.6.0.0 Little Big Mouse
LBM_VERSION=5.7.0-beta.1 5.7.0.0 Little Big Mouse

The Linux cargo build is unchanged.

That local check used mingw windres; CI builds MSVC and goes through rc.exe, which is a different resource compiler — so this PR's own run is the first real test of that path. The new "Verify hook version resource" step asserts on the built exe rather than on the build script, because every failure mode here is silent: a missing resource compiler, a props file that stops parsing, all leave a nameless exe that still builds and still runs.

Note on the managed side

The UI csproj sets no <Product>/<Company>, so MSBuild defaults ProductName to the assembly name: LittleBigMouse.Ui.Avalonia, where the hook now says Little Big Mouse. If the SignPath artifact configuration ends up enforcing one product name across all signed binaries, those need setting too. I left it out deliberately — the natural home is Directory.Build.props, and that would also restamp the HLab submodule assemblies, which is your call rather than mine.

🤖 Generated with Claude Code

rustc emits no VERSIONINFO, and nothing here supplied one, so
LittleBigMouse.Hook.exe has been shipping with no product name, no version and
no copyright at all — next to a UI exe that carries all three. It shows in the
file properties and in Task Manager, and it leaves a code-signing artifact
configuration that constrains product/version metadata nothing to match on
(#535 groundwork).

build.rs stamps the resource, taking the version from LBM_VERSION when CI sets
it from the tag, else from Directory.Build.props. Reading the props file is the
point: it is already the single source of truth for the managed side, and
without it this crate would keep announcing its own 0.1.0 from inside a 5.6.0
installer. Parsed with roxmltree rather than searched for as a substring,
because that file names <Version> inside its own comment several lines above the
real element — a find() returns the comment body, which is how the first attempt
here produced a FILEVERSION of 0.0.0.0 under a paragraph of prose.

The string fields keep a full "5.7.0-beta.1"; VERSIONINFO's fixed part is four
u16s, so the numeric fields carry the same version with the suffix dropped.

winresource sits in plain [build-dependencies], not under cfg(windows): build
dependencies resolve against the host, so gating it that way would break a Linux
host cross-compiling to Windows. build.rs returns early on CARGO_CFG_TARGET_OS
instead, leaving the Linux build untouched.

CI asserts on the built exe rather than on the build script, because every way
this fails is silent — a missing resource compiler, a props file that stops
parsing — and still yields an exe that builds and runs.

Verified by cross-compiling to x86_64-pc-windows-gnu: FILEVERSION 5.6.0.0 from
the props file, 5.7.0.0 with LBM_VERSION=5.7.0-beta.1, and the Linux build
unchanged.
@mgth
mgth merged commit 6925ca2 into master Aug 3, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant