diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a0e5e9..9f7b592 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,14 @@ a section is written. ## [Unreleased] +Nothing yet. + +## [0.3.0] - 2026-09-23 + +The configuration applies as you save it, a broken one says so, the games +you marked yourself in the Game Bar are followed too, and the watcher costs +a twelfth of what it did at rest. + ### Added - The watcher reads `config.toml` again whenever you save it, within a @@ -29,11 +37,11 @@ a section is written. *Edit configuration* opens the file, and saving a good one brings the icon back, with a notification saying the watcher is watching again — also when the fix came while the watcher was stopped. - - Games you marked yourself with *Remember this is a game* in the Game Bar are detected like any other, from their launch — or from the moment you - tick the box, in the middle of a game. Windows never tells the rest of the - system about those, which is why they used to go unnoticed. + tick the box, in the middle of a game. Windows does not start, for those, + the signal the program used to watch alone, which is why they went + unnoticed. - At start, the log says which of the games you marked Microsoft's own list now knows, so you can untick them and let Windows recognise them itself. `status` lists the games you marked and says the same. @@ -130,6 +138,7 @@ and when it stops, on Windows' own signal that a game is running. including the scheduled tasks a program that needs administrator rights requires, and a Windows power plan. -[Unreleased]: https://github.com/Geeooff/GameModeExecutor/compare/v0.2.0...HEAD +[Unreleased]: https://github.com/Geeooff/GameModeExecutor/compare/v0.3.0...HEAD +[0.3.0]: https://github.com/Geeooff/GameModeExecutor/compare/v0.2.0...v0.3.0 [0.2.0]: https://github.com/Geeooff/GameModeExecutor/compare/v0.1.0...v0.2.0 [0.1.0]: https://github.com/Geeooff/GameModeExecutor/releases/tag/v0.1.0 diff --git a/Cargo.lock b/Cargo.lock index b6b7111..6dea312 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -171,7 +171,7 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "game-mode-executor" -version = "0.2.0" +version = "0.3.0" dependencies = [ "anyhow", "clap", diff --git a/Cargo.toml b/Cargo.toml index 81ab6cb..097209a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "game-mode-executor" -version = "0.2.0" +version = "0.3.0" authors = ["Geoffrey Vancoetsem"] edition = "2024" # Let chains, stable since 1.88. diff --git a/docs/design/08-distribution.md b/docs/design/08-distribution.md index fdd1291..f0b26ce 100644 --- a/docs/design/08-distribution.md +++ b/docs/design/08-distribution.md @@ -304,6 +304,29 @@ only proposed: shortcut is a package change and would go with the recipes artefact if that is taken; the reload is the next lot's. +## The package that held one piece — 2026-09-23 + +Preparing 0.3.0, the local `build.ps1 release` said *release OK*: 102 ICE +evaluators clean, the changelog section found, the binaries stamped. The +installer weighed 88 KB, against 1.5 MB for 0.2.0. Its `files.cab` stream +was 20,378 bytes, for two executables of 1.4 MB each. + +`makecab`'s default disk is a 1.44 MB floppy. The two executables had grown +by some 50 KB each since 0.2.0 and compressed, together, to 1,476,966 +bytes — just over one floppy, where 0.2.0's had fitted by twenty +kilobytes. So `makecab` spanned two cabinets, and with a fixed +`CabinetNameTemplate` the second overwrote the first under the same name. +The package kept the last piece; the `File` table still listed all four +files, which is all the evaluators check, and `msi.ps1` only checked that +a cabinet existed. Published, it would have failed on every machine — and +the first to meet it would have been the updater, on the update meant to +close [Lot 13](13-updating.md). + +`msi.ps1` now asks for one cabinet whatever its size (`MaxDiskSize=0`), +and refuses a package whose cabinet does not list, through `expand -D`, +every file the package installs, or whose build left more than one +cabinet. Caught by looking at a number that had no reason to change. + ## Versioning Decided 2026-09-17, when the question came up before publication: why the diff --git a/scripts/msi.ps1 b/scripts/msi.ps1 index 15cf60c..9ff2644 100644 --- a/scripts/msi.ps1 +++ b/scripts/msi.ps1 @@ -95,10 +95,16 @@ $work = Join-Path ([System.IO.Path]::GetTempPath()) "gamemode-executor-msi-$([gu New-Item -ItemType Directory $work | Out-Null try { # --- the cabinet --------------------------------------------------------- + # MaxDiskSize=0: one cabinet, however large. makecab's default disk is a + # 1.44 MB floppy, and with a fixed CabinetNameTemplate the second cabinet + # of a spanned set overwrites the first under the same name: on + # 2026-09-23 the 0.3.0 executables compressed to 1,476,966 bytes, just + # over, and the package came out at 88 KB holding the last 20 KB piece. $ddf = @( '.OPTION EXPLICIT', '.Set CabinetNameTemplate=files.cab', ".Set DiskDirectoryTemplate=$work", + '.Set MaxDiskSize=0', '.Set CompressionType=LZX', '.Set Cabinet=on', '.Set Compress=on', @@ -116,6 +122,13 @@ try { $null = & makecab.exe /F $ddfPath $cab = Join-Path $work 'files.cab' if (-not (Test-Path $cab)) { throw 'makecab produced no cabinet' } + # The cabinet must hold every file, whole: its existence proved nothing + # the day it held one piece of two. `expand -D` lists what it contains. + $listed = @(& expand.exe -D $cab | ForEach-Object { if ($_ -match ':\s+(\S+)\s*$') { $Matches[1] } }) + foreach ($f in $files) { + if ($listed -notcontains $f.Key) { throw "the cabinet lacks $($f.Key) ($($f.Path)); makecab listed: $($listed -join ', ')" } + } + if (@(Get-ChildItem $work -Filter '*.cab').Count -ne 1) { throw 'makecab produced more than one cabinet' } # --- the database -------------------------------------------------------- $installer = New-Object -ComObject WindowsInstaller.Installer