devicehost: stop re-signing and fix MSI installer failing to replace wsldevicehost.dll (#40075)
* devicehost: stop re-signing and fix MSI installer failing to replace wsldevicehost.dll * pr feedback * use MSIRMSHUTDOWN = 1 instead of custom action --------- Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
Ben Hillis committed
Apr 6, 2026 at 15:10 UTC
f9f1c38d9f42e2a19b2153500d94290ba6a89dc9
5 files changed
+16
-5
.pipelines/build-stage.yml
+1
-1
@@ -24,7 +24,7 @@ parameters:
24
type: object
25
default:
26
- target: "wsl;libwsl;wslg;wslservice;wslhost;wslrelay;wslinstaller;wslinstall;initramfs;wslserviceproxystub;wslsettings;wslinstallerproxystub;testplugin"
27
- pattern: "wsl.exe,libwsl.dll,wslg.exe,wslservice.exe,wslhost.exe,wslrelay.exe,wslinstaller.exe,wslinstall.dll,wslserviceproxystub.dll,wslsettings/wslsettings.dll,wslsettings/wslsettings.exe,wslinstallerproxystub.dll,wsldevicehost.dll,WSLDVCPlugin.dll,testplugin.dll,wsldeps.dll"
27
+ pattern: "wsl.exe,libwsl.dll,wslg.exe,wslservice.exe,wslhost.exe,wslrelay.exe,wslinstaller.exe,wslinstall.dll,wslserviceproxystub.dll,wslsettings/wslsettings.dll,wslsettings/wslsettings.exe,wslinstallerproxystub.dll,WSLDVCPlugin.dll,testplugin.dll,wsldeps.dll"
28
- target: "msixgluepackage"
29
pattern: "gluepackage.msix"
30
- target: "msipackage"
CMakeLists.txt
-1
@@ -157,7 +157,6 @@ set (GENERATED_DIR ${CMAKE_BINARY_DIR}/generated)
157
file(MAKE_DIRECTORY ${GENERATED_DIR})
158
159
set(PACKAGE_CERTIFICATE ${GENERATED_DIR}/dev-cert.pfx)
160
-file(CREATE_LINK ${WSL_DEVICE_HOST_SOURCE_DIR}/bin/${TARGET_PLATFORM}/wsldevicehost.dll ${BIN}/wsldevicehost.dll)
160
file(CREATE_LINK ${WSLG_SOURCE_DIR}/${TARGET_PLATFORM}/${WSLG_TS_PLUGIN_DLL} ${BIN}/${WSLG_TS_PLUGIN_DLL})
161
file(CREATE_LINK ${WSLDEPS_SOURCE_DIR}/bin/wsldeps.dll ${BIN}/wsldeps.dll)
162
msipackage/package.wix.in
+3
-2
@@ -221,6 +221,8 @@
221
N.B. It shouldn't be started on install because it will fail to start if the OC is missing,
222
which would fail the install. -->
223
<ServiceControl Id="StopService" Stop="both" Remove="uninstall" Name="WSLService" Wait="yes" />
224
+
225
+ <File Id="wsldevicehost.dll" Source="${WSL_DEVICE_HOST_SOURCE_DIR}/bin/${TARGET_PLATFORM}/wsldevicehost.dll" />
226
</Component>
227
228
<Component Id="wslg" Guid="F0C8D6BA-1502-41E7-BF72-D93DFA134731" UninstallWhenSuperseded="yes" DisableRegistryReflection="yes" Bitness="always64">
@@ -232,7 +234,6 @@
234
<File Id="rdpnanoTransport.dll" Source="${MSRDC_SOURCE_DIR}/${TARGET_PLATFORM}/rdpnanoTransport.dll" />
235
<File Id="RdpWinStlHelper.dll" Source="${MSRDC_SOURCE_DIR}/${TARGET_PLATFORM}/RdpWinStlHelper.dll" />
236
<?endif?>
235
- <File Id="wsldevicehost.dll" Source="${PACKAGE_INPUT_DIR}/wsldevicehost.dll" />
237
<File Id="${WSLG_TS_PLUGIN_DLL}" Source="${PACKAGE_INPUT_DIR}/${WSLG_TS_PLUGIN_DLL}" />
238
239
<!-- MSRDC Plugin registration -->
@@ -551,7 +552,7 @@
552
<!-- Force all applications to exit during upgrade.
553
See: https://learn.microsoft.com/en-us/windows/win32/msi/msirmshutdown
554
-->
554
- <Property Id="MSIRMSHUTDOWN" Value="0" Secure="yes" />
555
+ <Property Id="MSIRMSHUTDOWN" Value="1" Secure="yes" />
556
</Package>
557
</Wix>
558
packages.config
+1
-1
@@ -18,7 +18,7 @@
18
<package id="Microsoft.WSL.bsdtar" version="0.0.2-2" />
19
<package id="Microsoft.WSL.Dependencies.amd64fre" version="10.0.27820.1000-250318-1700.rs-base2-hyp" targetFramework="native" />
20
<package id="Microsoft.WSL.Dependencies.arm64fre" version="10.0.27820.1000-250318-1700.rs-base2-hyp" targetFramework="native" />
21
- <package id="Microsoft.WSL.DeviceHost" version="1.1.48-0" />
21
+ <package id="Microsoft.WSL.DeviceHost" version="1.2.10-0" />
22
<package id="Microsoft.WSL.Kernel" version="6.6.114.1-1" targetFramework="native" />
23
<package id="Microsoft.WSL.LinuxSdk" version="1.20.0" targetFramework="native" />
24
<package id="Microsoft.WSL.TestDistro" version="2.7.1-1" />
test/windows/InstallerTests.cpp
+11
@@ -175,8 +175,17 @@ class InstallerTests
175
return wsl::windows::common::registry::ReadString(m_lxssKey.get(), L"MSI", L"ProductCode", L"");
176
}
177
178
+ // Release any in-process COM DLLs (e.g. wslserviceproxystub.dll loaded by prior tests)
179
+ // so the Restart Manager doesn't detect the test process as holding files.
180
+ // This avoids install failures on older Server SKUs where the RM has stricter silent-mode behavior.
181
+ static void PrepareForMsiOperation()
182
+ {
183
+ CoFreeUnusedLibrariesEx(0, 0);
184
+ }
185
+
186
void UninstallMsi()
187
{
188
+ PrepareForMsiOperation();
189
auto productCode = GetMsiProductCode();
190
VERIFY_IS_FALSE(productCode.empty());
191
@@ -185,6 +194,7 @@ class InstallerTests
194
195
void InstallMsi()
196
{
197
+ PrepareForMsiOperation();
198
CallMsiExec(std::format(L"/qn /norestart /i {} /L*V {}", m_msiPath, GenerateMsiLogPath()));
199
}
200
@@ -367,6 +377,7 @@ class InstallerTests
377
LogInfo("Installing: %ls", installerFile.c_str());
378
if (wsl::shared::string::EndsWith<wchar_t>(installerFile, L".msi"))
379
{
380
+ PrepareForMsiOperation();
381
CallMsiExec(std::format(L"/qn /norestart /i {} /L*V {}", installerFile, GenerateMsiLogPath()));
382
}
383
else