Give the hook daemon a Windows version resource - #537
Merged
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Groundwork for #535 / #536, but a fix in its own right.
The gap
rustcemits noVERSIONINFOresource and nothing in this crate supplied one, soLittleBigMouse.Hook.exehas 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.rsstamps the resource. The version comes fromLBM_VERSIONwhen CI sets it from the tag, otherwise fromDirectory.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.0from inside a 5.6.0 installer — exactly the drift a signing policy would reject, discovered at release time.Two details worth a look:
roxmltree, not substring-matched.Directory.Build.propsnames<Version>inside its own comment several lines above the real element, sofind("<Version>")returns the comment body. My first attempt did exactly that and producedFILEVERSION 0, 0, 0, 0with a paragraph of prose as theFileVersionstring.roxmltreeis already a dependency of this crate.winresourceis in plain[build-dependencies], not undercfg(windows). Build dependencies resolve against the host, so gating it that way silently breaks a Linux host cross-compiling to Windows.build.rsreturns early onCARGO_CFG_TARGET_OSinstead; the Linux build is untouched.String fields keep the full version (
5.7.0-beta.1); the fixed part ofVERSIONINFOis fouru16s, so the numeric fields carry the same version with the pre-release suffix dropped.Verification
Cross-compiled to
x86_64-pc-windows-gnuand read back out of the PE:FILEVERSIONProductNameDirectory.Build.props)5.6.0.0LBM_VERSION=5.7.0-beta.15.7.0.0The Linux
cargo buildis unchanged.That local check used mingw
windres; CI builds MSVC and goes throughrc.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 defaultsProductNameto the assembly name:LittleBigMouse.Ui.Avalonia, where the hook now saysLittle 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 isDirectory.Build.props, and that would also restamp the HLab submodule assemblies, which is your call rather than mine.🤖 Generated with Claude Code