Skip to content

Refresh Explorer association cache after registering file associations#37

Merged
tommyjcarpenter merged 1 commit into
mainfrom
windows-assoc-cache-refresh
Jun 26, 2026
Merged

Refresh Explorer association cache after registering file associations#37
tommyjcarpenter merged 1 commit into
mainfrom
windows-assoc-cache-refresh

Conversation

@tommyjcarpenter

Copy link
Copy Markdown
Owner

install_file_associations wrote each per-user class registration but never told Explorer to refresh its cached file-type defaults, so a newly registered association only took effect after the next sign-in or an Explorer restart. For an extension Explorer had already resolved to another app (e.g. .json -> Visual Studio) the stale default kept winning on double-click even though the new type showed up in "Open with". Extensions nothing else had claimed (.md, .yaml, .toml) had no cached default, so they resolved fresh to the new handler and masked the gap.

Changes:

  • Add _notify_assoc_changed(), which calls SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, ...) via ctypes to invalidate Explorer's association cache. It uses a local import ctypes to match the module's existing pattern for Windows-only APIs (winreg), so the module still imports cleanly on the Linux CI runner.
  • Call it once in install_file_associations after the registration loop, so the broadcast fires a single time regardless of how many extensions were registered.

No unit test added: the helper is a thin shell32 call with no return value to assert on; the existing import smoke test already covers it loading. make ci (ruff check + format, 18 unittests, schema) passes locally, and the call was confirmed live on Windows 11.

`install_file_associations` wrote each per-user class registration but never told
Explorer to refresh its cached file-type defaults, so a newly registered association only
took effect after the next sign-in or an Explorer restart. For an extension Explorer had
already resolved to another app (e.g. `.json` -> Visual Studio) the stale default kept
winning on double-click even though the new type showed up in "Open with". Extensions
nothing else had claimed (`.md`, `.yaml`, `.toml`) had no cached default, so they resolved
fresh to the new handler and masked the gap.

Changes:
- Add `_notify_assoc_changed()`, which calls `SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, ...)` via `ctypes` to invalidate Explorer's association cache. It uses a local `import ctypes` to match the module's existing pattern for Windows-only APIs (`winreg`), so the module still imports cleanly on the Linux CI runner.
- Call it once in `install_file_associations` after the registration loop, so the broadcast fires a single time regardless of how many extensions were registered.

No unit test added: the helper is a thin `shell32` call with no return value to assert on; the existing import smoke test already covers it loading.
Copilot AI review requested due to automatic review settings June 26, 2026 10:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Ensures newly registered per-user Windows file associations take effect immediately by explicitly invalidating Explorer’s association cache after registry writes, avoiding the need for sign-out or restarting Explorer.

Changes:

  • Add a Windows-only helper _notify_assoc_changed() that calls SHChangeNotify(SHCNE_ASSOCCHANGED, ...) via ctypes to refresh Explorer’s association cache.
  • Call _notify_assoc_changed() once at the end of install_file_associations() (after processing all configured associations) and log the refresh action.
  • Expand the install_file_associations docstring to document the refresh behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@tommyjcarpenter tommyjcarpenter merged commit ceb75a9 into main Jun 26, 2026
6 checks passed
@tommyjcarpenter tommyjcarpenter deleted the windows-assoc-cache-refresh branch June 26, 2026 10:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants