msi: eliminate Warning 1946 dialog by moving shortcut properties to custom action#40219
msi: eliminate Warning 1946 dialog by moving shortcut properties to custom action#40219yeelam-gordon wants to merge 5 commits intomasterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the WSL MSI installer to eliminate MSI Warning 1946 dialogs/warnings caused by MsiShortcutProperty updates failing under .lnk sharing contention, by moving shortcut property setting into a deferred custom action that retries via IPropertyStore.
Changes:
- Removes WiX
ShortcutPropertyentries for WSL shortcuts and adds a deferredRepairShortcutPropertiescustom action scheduled inInstallExecuteSequence. - Implements
RepairShortcutPropertiesand a retry helper inwslinstall.dllto set shortcut properties via COM with backoff on sharing/lock violations. - Adds a PowerShell test harness for running install/uninstall scenarios under simulated shortcut file contention.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
msipackage/package.wix.in |
Drops ShortcutProperty table usage and schedules new RepairShortcutProperties custom action. |
src/windows/wslinstall/DllMain.cpp |
Adds COM-based shortcut property repair helper + exported custom action implementation. |
src/windows/wslinstall/wslinstall.def |
Exports RepairShortcutProperties from wslinstall.dll. |
src/windows/wslinstall/CMakeLists.txt |
Links propsys.lib for property system APIs. |
test/shortcut_property_test/Test-AllScenariosMsi.ps1 |
Adds a contention-oriented MSI install scenario runner script. |
test/shortcut_property_test/.gitignore |
Ignores temp/log artifacts generated by the new test script. |
65b6191 to
67bbfb6
Compare
…ustom action Warning 1946 occurs when the MSI engine's built-in ShortcutPropertyCreate fails due to a sharing violation on the .lnk file. When run with UI (double-clicking the .msi), this shows a MODAL DIALOG that blocks the install until the user clicks OK. When run via wsl --update, it prints a warning to the console. Both are disruptive to users. Root cause: any process holding the .lnk file open (search indexer, AV, PowerToys Run, shell extensions) races with MsiShortcutProperty writes. The MSI engine has no retry logic and no way to suppress the dialog. Fix: Remove all <ShortcutProperty> declarations from the WiX file so the MSI engine never attempts ShortcutPropertyCreate (eliminating the warning/dialog source entirely). Instead, a new RepairShortcutProperties deferred custom action sets all shortcut properties using COM IPropertyStore with: - STGM_READWRITE | STGM_SHARE_DENY_NONE (non-exclusive file access) - Retry loop (10 attempts, 100ms delay) on sharing violations - Best-effort (returns NOERROR even on failure, with TraceLogging) Properties handled: - WSL.lnk: AppUserModel.ID, AppUserModel.ToastActivatorCLSID - WSL Settings.lnk: AppUserModel.IsSystemComponent Also suppress Warning 1946 in MsiMessageCallback for the wsl --update console path as a defense-in-depth measure. Refs: #13469, #11276, #12759 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
67bbfb6 to
4af4dc7
Compare
Replace GetProductInfo(LOWORD(GetVersion()), ...) || true with a simple block scope. The actual workstation check already uses GetVersionExW, so the outer GetProductInfo call was dead code that triggered C4996. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Document that the custom action repairs both WSL.lnk and WSL Settings.lnk shortcuts, with references to the relevant GitHub issues. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
benhillis
left a comment
There was a problem hiding this comment.
Please add a test to InstallerTests that exhibits this behavior.
|
@yeelam-gordon: the copilot comment about GetVersionExW is worth looking at. LGTM otherwise, once the InstallerTests related comment is addressed |
OneBlue
left a comment
There was a problem hiding this comment.
I'm a bit conflicted on what we should do here. This warning isn't great, but it's very likely caused by another application locking our shortcut.
The warning isn't great, but it's also non-fatal, and only requires user action when the MSI is installation manually, which is relatively rare.
Another parameter to this is that installer changes are high-risk. For instance a bug that would crash the installer during a custom action could leave the user's machine in a broken state, which has a very high potential of negative impact.
Additionally, this new logic doesn't actually solve the issue, but only retries for a given amount of time, and then fails without warning, which would make root causing this harder.
Taking all of this into account, my opinion would be to leave the warning as-is for now and look into root-causing the issue if we truly want to eliminate the warning.
@benhillis : what are you thoughts on this ?
Use the existing IsWindowsServer() helper (from VersionHelpers.h) instead of deprecated GetVersionExW for workstation detection (per ptrivedi/copilot). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Addressed review feedback in latest push:
|
…etsShortcutProperties, InstallSetsShortcutPropertiesUnderContention) Agent-Logs-Url: https://github.com/microsoft/WSL/sessions/cdab304d-bddc-494b-8a86-c6d5cfdafd1b Co-authored-by: yeelam-gordon <73506701+yeelam-gordon@users.noreply.github.com>
Added two tests in commit ee97abb:
Also added |
Isn't the root cause a third-party process locking the .lnk? I understand it would be good to find what process, but we've seen that it could be different ones. My thought is, do these properties have to be set in the installer? What if they are applied later during startup or something? Do they need the banner etc. on the very first install before WSL has even run? |
|
This is a ton of code to work around what seems to be an issue with the MSI infrastructure. |
Summary
Eliminates Warning 1946 ΓÇö the modal dialog popup (or console warning) during WSL installation caused by shortcut property sharing violations.
Before
During MSI install, the engine sets shortcut properties via the
MsiShortcutPropertytable. If any process holds the.lnkfile open (search indexer, AV, PowerToys Run, shell extensions),ShortcutPropertyCreatefails withERROR_SHARING_VIOLATION(HRESULT 32):.msi: Modal dialog popup blocks the install until user clicks OKwsl --update: Warning text printed to consoleThis affects any process holding the file ΓÇö not just PowerToys (#12759 reported it without PowerToys installed).
After
ShortcutPropertyentries removed from WiX, so the MSI engine never attemptsShortcutPropertyCreateRepairShortcutPropertiesdeferred custom action sets all properties via COMIPropertyStorewith non-exclusive access (STGM_SHARE_DENY_NONE) and exponential backoff retry (50ms→100ms→200ms...→1s cap, 5s total timeout)Properties handled
WSL.lnkSystem.AppUserModel.IDMicrosoft.WSLWSL.lnkSystem.AppUserModel.ToastActivatorCLSID{2B9C59C3-...}WSL Settings.lnkSystem.AppUserModel.IsSystemComponenttrueWhy not just suppress the warning?
MsiSetExternalUIcallback suppression only works forwsl --update(INSTALLUILEVEL_NONE).msidouble-click uses the MSI engine's built-in UI ΓÇö no way to suppress the modal dialog from the package sideEmbeddedUIcould work but requires a new DLL for filtering one warningShortcutPropertyentries is the only approach that eliminates the warning across all install pathsLifecycle coverage
RemoveFileTesting
8 real MSI install scenarios with active
FileSystemWatchercontention — each ran full uninstall→lock→install→verify cycle:Each scenario verified: no Warning 1946 in MSI log, CA returned success, MSI exit 0,
AppUserModel.IDandToastActivatorCLSIDset correctly via COMIPropertyStoreread-back.Test script:
test/shortcut_property_test/Test-AllScenariosMsi.ps1(run as admin)PR Checklist
Changes
msipackage/package.wix.inShortcutPropertyentries, addRepairShortcutPropertiesCA declaration + sequencesrc/windows/wslinstall/DllMain.cppRepairShortcutProperties+SetShortcutPropertyWithRetryimplementationsrc/windows/wslinstall/wslinstall.defRepairShortcutPropertiessrc/windows/wslinstall/CMakeLists.txtpropsys.libtest/shortcut_property_test/