diff --git a/src/windows/common/WslClient.cpp b/src/windows/common/WslClient.cpp index e1f3a0f1f..5e9f952d7 100644 --- a/src/windows/common/WslClient.cpp +++ b/src/windows/common/WslClient.cpp @@ -1277,7 +1277,11 @@ int Uninstall() const auto exitCode = wsl::windows::common::install::UninstallViaMsi(logFile.c_str(), &wsl::windows::common::install::MsiMessageCallback); - if (exitCode != 0) + if (exitCode == ERROR_SUCCESS_REBOOT_REQUIRED) + { + wsl::windows::common::wslutil::PrintSystemError(ERROR_SUCCESS_REBOOT_REQUIRED); + } + else if (exitCode != 0) { clearLogs.release(); THROW_HR_WITH_USER_ERROR( diff --git a/src/windows/common/install.cpp b/src/windows/common/install.cpp index 740e382d2..a268f8bf6 100644 --- a/src/windows/common/install.cpp +++ b/src/windows/common/install.cpp @@ -104,7 +104,11 @@ int UpdatePackageImpl(bool preRelease, bool repair) const auto exitCode = UpgradeViaMsi(downloadPath.c_str(), L"", logFile.c_str(), &MsiMessageCallback); - if (exitCode != 0) + if (exitCode == ERROR_SUCCESS_REBOOT_REQUIRED) + { + PrintSystemError(ERROR_SUCCESS_REBOOT_REQUIRED); + } + else if (exitCode != 0) { clearLogs.release(); THROW_HR_WITH_USER_ERROR( @@ -358,15 +362,20 @@ int wsl::windows::common::install::UpdatePackage(bool PreRelease, bool Repair) UINT wsl::windows::common::install::UpgradeViaMsi( _In_ LPCWSTR PackageLocation, _In_opt_ LPCWSTR ExtraArgs, _In_opt_ LPCWSTR LogFile, _In_ const std::function& Callback) { - WriteInstallLog(std::format("Upgrading via MSI package: {}. Args: {}", PackageLocation, ExtraArgs != nullptr ? ExtraArgs : L"")); + // Always suppress MSI-initiated reboots. With INSTALLUILEVEL_NONE, Windows Installer + // will silently reboot the machine if files are in use and REBOOT is not suppressed. + std::wstring args = L"REBOOT=ReallySuppress"; + if (ExtraArgs != nullptr && *ExtraArgs != L'\0') + { + args = std::wstring(ExtraArgs) + L" " + args; + } + + WriteInstallLog(std::format("Upgrading via MSI package: {}. Args: {}", PackageLocation, args)); ConfigureMsiLogging(LogFile, Callback); - auto result = MsiInstallProduct(PackageLocation, ExtraArgs); - WSL_LOG( - "MsiInstallResult", - TraceLoggingValue(result, "result"), - TraceLoggingValue(ExtraArgs != nullptr ? ExtraArgs : L"", "ExtraArgs")); + auto result = MsiInstallProduct(PackageLocation, args.c_str()); + WSL_LOG("MsiInstallResult", TraceLoggingValue(result, "result"), TraceLoggingValue(args.c_str(), "ExtraArgs")); WriteInstallLog(std::format("MSI upgrade result: {}", result)); @@ -382,7 +391,7 @@ UINT wsl::windows::common::install::UninstallViaMsi(_In_opt_ LPCWSTR LogFile, _I ConfigureMsiLogging(LogFile, Callback); - auto result = MsiConfigureProduct(productCode.c_str(), 0, INSTALLSTATE_ABSENT); + auto result = MsiConfigureProductEx(productCode.c_str(), 0, INSTALLSTATE_ABSENT, L"REBOOT=ReallySuppress"); WSL_LOG("MsiUninstallResult", TraceLoggingValue(result, "result")); WriteInstallLog(std::format("MSI package uninstall result: {}", result)); diff --git a/src/windows/wslinstaller/exe/WslInstaller.cpp b/src/windows/wslinstaller/exe/WslInstaller.cpp index a4019e612..f370d6498 100644 --- a/src/windows/wslinstaller/exe/WslInstaller.cpp +++ b/src/windows/wslinstaller/exe/WslInstaller.cpp @@ -79,7 +79,20 @@ std::pair InstallMsipackageImpl() auto result = wsl::windows::common::install::UpgradeViaMsi( GetMsiPackagePath().c_str(), L"SKIPMSIX=1", logFile.has_value() ? logFile->c_str() : nullptr, messageCallback); - WSL_LOG("MSIUpgradeResult", TraceLoggingValue(result, "result"), TraceLoggingValue(errors.c_str(), "errorMessage")); + // ERROR_SUCCESS_REBOOT_REQUIRED (3010) means the install succeeded but some files + // will be replaced on the next reboot. Treat as success since the service runs + // silently with no user-facing console. + const bool rebootRequired = (result == ERROR_SUCCESS_REBOOT_REQUIRED); + if (rebootRequired) + { + result = ERROR_SUCCESS; + } + + WSL_LOG( + "MSIUpgradeResult", + TraceLoggingValue(result, "result"), + TraceLoggingValue(rebootRequired, "rebootRequired"), + TraceLoggingValue(errors.c_str(), "errorMessage")); return {result, errors}; }