mirror of
https://github.com/microsoft/WSL.git
synced 2026-05-31 16:13:47 -05:00
When the embedded MSI in the Microsoft Store MSIX cannot replace a locked file (most commonly system.vhd, which is mounted whenever a WSL2 instance is running), Windows Installer renames the existing file to C:\Windows\Installer\Config.Msi\<hex>.rbf, schedules the new file via MoveFileEx(MOVEFILE_DELAY_UNTIL_REBOOT), and returns ERROR_SUCCESS_REBOOT_REQUIRED (3010). InstallMsipackageImpl in wslinstaller silently converted 3010 to ERROR_SUCCESS and returned success to its caller. The user was told nothing; their next wsl invocation hit a now-empty C:\Program Files\WSL install dir (system.vhd physically gone until reboot) and produced a confusing "vhd missing" failure - perceived as data loss. This change: * Stops swallowing 3010 in InstallMsipackageImpl. The MSI log is now preserved on 3010 (previously deleted) to aid diagnostics. * Sets a volatile registry marker (HKLM\Software\Microsoft\Windows\CurrentVersion\Lxss\MSI\RebootPending) using REG_OPTION_VOLATILE so the kernel auto-clears it on reboot. No cleanup path is needed; the marker is gone iff the user has rebooted. * Adds a marker check in LxssUserSession::_CreateInstance (service side) which throws a localized user-facing error (MessageUpdateRebootRequired) any time a client tries to launch a distro while the reboot is pending. This catches all distro-launching client paths through the single service entry point: wsl.exe (lifted and MSI-installed), wslg.exe, bash.exe, VS Code Remote-WSL, etc. * Also checks the marker on entry to CallMsiPackage and throws on 3010 in WaitForMsiInstall, so the wsl --update / lifted-client paths surface the same error. User-visible behavior: > wsl WSL was updated but a system restart is required to complete the installation. Please reboot your machine and try again. Error code: Wsl/Service/CreateInstance/0x80070bc2 The user reboots; the volatile key is destroyed by the kernel; Windows' pending file-rename queue swaps the staged file into place; WSL works again. Adds an integration test, InstallerTests::UpgradeWithLockedFileReportsRebootRequired, that exercises the full path: uninstalls the MSI, memory-maps a dummy file at the install path to make it unrenameable, runs the MSIX installer to drive the WslInstaller service, polls for the marker, then verifies wsl echo OK fails with the expected message before cleaning up. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>