Skip to content

vscode: Correct file association icon paths#17196

Open
Timabliss wants to merge 2 commits intoScoopInstaller:masterfrom
Timabliss:fix/vscode-icon
Open

vscode: Correct file association icon paths#17196
Timabliss wants to merge 2 commits intoScoopInstaller:masterfrom
Timabliss:fix/vscode-icon

Conversation

@Timabliss
Copy link

@Timabliss Timabliss commented Feb 12, 2026

Description

This PR fixes an issue where file association icons were missing because VS Code extracts resources into a dynamic hash directory (e.g., current\591199df...\resources), but the registry templates pointed to the static root.

Changes

  1. post_install:
    • Added logic to sniff the dynamic version hash directory.
    • Updates $codedir variable in .reg templates to use the hash path for install-associations.reg .
    • Preserves the static root path for install-github-integration.reg (as it requires the executable path).
  2. uninstaller:
    • Added reg import "$dir\uninstall-associations.reg" which was missing, ensuring registry keys are properly cleaned up upon uninstall.

Testing

  • Installed vscode locally using the modified manifest.
  • Verified that .reg files are generated with the correct hash path.
  • Manually imported generated .reg files and verified that icons appear correctly in the context menu and file explorer.
  • Verified that Git integration still works (uses correct root path).
  • Uninstalled vscode and verified that registry keys (including CodeOSS)

Summary by CodeRabbit

  • New Features

    • Detects other installed app versions and unregisters their uninstall-related registry entries to prevent conflicts.
    • Uninstaller now imports additional uninstall-association registry data for more complete cleanup.
    • Post-install computes and uses a dynamic install target path when resolving registry substitutions.
  • Bug Fixes

    • More reliable registry substitutions and path resolution during install/uninstall to improve correctness and avoid incorrect registry entries.

@coderabbitai
Copy link

coderabbitai bot commented Feb 12, 2026

Walkthrough

Adds PowerShell post-install logic to compute a dynamic install target path (from bin\code\VERSIONFOLDER or hash), use it for reg-file path substitutions, unregister other-version uninstall registry entries, and import uninstall-associations.reg during uninstall; includes minor formatting tweaks.

Changes

Cohort / File(s) Summary
VSCode bucket
bucket/vscode.json
Adds post_install PowerShell logic to compute targetPath (prefer bin\code\VERSIONFOLDER, fallback to hash), replace $codedir substitutions with conditional targetPath vs $dirpath, unregister other-version uninstall reg files via regedit /u, and import uninstall-associations.reg during uninstall. Minor formatting/indentation changes.

Sequence Diagram(s)

sequenceDiagram
    participant Installer
    participant PowerShell
    participant FileSystem
    participant Registry

    Installer->>PowerShell: run post_install
    PowerShell->>FileSystem: check installDir\bin\code for VERSIONFOLDER
    alt VERSIONFOLDER found
        PowerShell->>FileSystem: set targetPath = installDir\VERSIONFOLDER
    else
        PowerShell->>FileSystem: compute hash-based targetPath
    end
    PowerShell->>FileSystem: update .reg files (replace $codedir with targetPath or $dirpath for GitHub)
    PowerShell->>Registry: import updated uninstall .reg files
    alt other-version reg files present
        PowerShell->>Registry: run regedit /u on matching uninstall .reg files
    end
    Installer->>Registry: on uninstall import uninstall-associations.reg
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • z-Fng

Poem

🐰 I hopped through folders, sniffed a VERSION trace,

Picked the right path, left no old reg in place,
I swapped the strings and unhooked their ties,
Now installers sing and old keys say goodbyes,
A tiny rabbit cheer for tidy installs.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: correcting file association icon paths in the VSCode manifest to use dynamic hash directories.
Description check ✅ Passed The description provides clear context, explains the problem, documents changes, and includes testing verification, though it is incomplete.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Contributor

Your changes did not pass all checks.

Please address the issues in the manifest and comment starting with /verify to rerun the checks.

vscode

  • Lint
  • Description
  • License
  • Hashes
  • Checkver
  • Autoupdate
  • Autoupdate Hash Extraction

Check the full log for details.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@bucket/vscode.json`:
- Around line 37-42: Reduce the indentation of the nested if/else block inside
the Test-Path section so lines assigning $targetDir and the subsequent
$content.Replace call align with the surrounding block: move the lines
containing "if ($_ -match 'github') {", "$targetDir = $dirpath", "} else {",
"$targetDir = $hashPath", "}" and "$content = $content.Replace('$codedir',
$targetDir)" left by 4 spaces to match the indentation of the Test-Path block
and surrounding statements; ensure $targetDir, $dirpath, $hashPath and the
$content.Replace('$codedir', $targetDir) call remain unchanged.
🧹 Nitpick comments (1)
bucket/vscode.json (1)

32-33: Hash directory detection is a reasonable heuristic, but consider tightening the pattern.

The regex ^[a-z0-9]{10,}$ (case-insensitive via -match) could match directories unrelated to VS Code's resource hash. If the hash is always a hex string of a known fixed length (e.g., the PR description shows an 8-char prefix 591199df), you could narrow the pattern (e.g., ^[a-f0-9]{8,}$) to reduce false-positive risk.

Also, Get-ChildItem without -Force won't list hidden directories, which is fine here, but note that if multiple directories match, -First 1 picks alphabetically — not necessarily the correct one. Worth confirming VS Code only ever creates a single such directory.

@Timabliss
Copy link
Author

/verify

@github-actions
Copy link
Contributor

All changes look good.

Wait for review from human collaborators.

vscode

  • Lint
  • Description
  • License
  • Hashes
  • Checkver
  • Autoupdate
  • Autoupdate Hash Extraction

Check the full log for details.

@Timabliss
Copy link
Author

/verify

@Timabliss Timabliss marked this pull request as draft February 13, 2026 08:33
@github-actions
Copy link
Contributor

Your changes did not pass all checks.

Please address the issues in the manifest and comment starting with /verify to rerun the checks.

vscode

  • Lint
  • Description
  • License
  • Hashes
  • Checkver
  • Autoupdate
  • Autoupdate Hash Extraction

Check the full log for details.

Major refactor of the `post_install` logic to improve robustness and registry hygiene:

1. Deterministic Version Detection (Source of Truth):
   Instead of unreliable directory sniffing, we now parse the official `bin/code` shell script to extract the `VERSIONFOLDER` variable. This is the upstream source of truth for the version hash.

2. Dynamic Registry Template Injection:
   - Context Menus & Associations: Injected with the resolved hash path (e.g., `$dir\<hash>`).
   - GitHub Integration: Injected with the root path (`$dir`), as per standard behavior.
   - Handled via variable replacement in `.reg` templates during runtime.

3. Update-Triggered Registry Cleanup:
   Implemented a "Clean Slate" policy. During an update (detected by the presence of older version directories matching `^[0-9.]+$`), the script automatically runs uninstall routines for the previous registration. This prevents registry pollution and ensures that HKCU keys strictly correspond to the current installation.
@Timabliss Timabliss marked this pull request as ready for review February 13, 2026 09:42
@Timabliss
Copy link
Author

/verify

@github-actions
Copy link
Contributor

All changes look good.

Wait for review from human collaborators.

vscode

  • Lint
  • Description
  • License
  • Hashes
  • Checkver
  • Autoupdate
  • Autoupdate Hash Extraction

Check the full log for details.

@Timabliss
Copy link
Author

Title:
Refactor: Use official bin/code as Source of Truth & Implement Registry Hygiene

Description:
I've completely rewritten the post_install script to address the fragility of directory structure detection.

Key Changes:

  • ⚡ Source of Truth:
    I discovered that the bin/code script (shipped by Microsoft) explicitly defines the VERSIONFOLDER variable.
    We now parse this file directly to get the hash, rather than "sniffing" the directory for random 10-char folders. This makes the logic deterministic and immune to user-created folders (like backups).
  • 🧹 Registry Hygiene (The "Clean Slate" Philosophy):
    I implemented a check to see if an update is occurring (by detecting other version directories via regex ^[0-9.]+$).
    If an old version is found, we proactively trigger the uninstall-*.reg logic before the new installation finishes. This ensures that:
  1. Stale keys from previous versions are removed.
  2. The registry remains clean and only points to the active version.
  • 🛡️ Robustness:
    Fixed edge cases where single-file results from Get-ChildItem caused .Count errors, and added regex filters to avoid false positives on non-version directories.

Ready for review! 🚀

@z-Fng z-Fng changed the title fix(vscode): inject dynamic hash path for file association icons vscode: Correct file association icon paths Feb 14, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@bucket/vscode.json`:
- Around line 68-77: The cleanup loop that builds $regFile in the block starting
with "$appRoot = Split-Path $dir -Parent" uses "regedit /s \"$regFile\"" which
is GUI-based and async; replace that call with the synchronous CLI "reg import
\"$regFile\"" to match the rest of the manifest. Locate the loop that iterates
over 'uninstall-associations', 'uninstall-context',
'uninstall-github-integration' (the $regFile variable) and swap the regedit
invocation for reg import so registry files are imported reliably under
UAC/elevation.

---

Duplicate comments:
In `@bucket/vscode.json`:
- Around line 46-47: The line containing "if ($_ -match 'github') {$tmppath =
$dirpath} else {$tmppath = $targetpath}" inside the same ForEach-Object block is
indented with 8 spaces while the other statements (e.g., the surrounding lines
that set $content and replace '$codedir') use 4 spaces; change that line's
indentation to 4 spaces so it matches the block's existing indentation style and
aligns with the other statements in the ForEach-Object.

Comment on lines +68 to 77
"$appRoot = Split-Path $dir -Parent",
"$otherVersions = @(Get-ChildItem $appRoot -Directory | Where-Object { $_.FullName -ne $dir -and $_.Name -ne 'current' -and ($_.Name -match '^[0-9.]+$') })",
"if ($otherVersions.Count -gt 0) {",
" 'uninstall-associations', 'uninstall-context', 'uninstall-github-integration' | ForEach-Object {",
" $regFile = \"$dir\\$_.reg\"",
" if (Test-Path $regFile) {",
" regedit /s \"$regFile\"",
" }",
" }",
"}"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Use reg import instead of regedit /s for consistency and reliability.

The uninstaller block (lines 83–85) uses reg import, but this cleanup block uses regedit /s. regedit is a GUI application — even with /s, it runs asynchronously and can behave differently under UAC/elevation. reg import is the CLI counterpart, runs synchronously, and is the standard used throughout Scoop manifests.

Proposed fix
     "'uninstall-associations', 'uninstall-context', 'uninstall-github-integration' | ForEach-Object {",
         "$regFile = \"$dir\\$_.reg\"",
         "if (Test-Path $regFile) {",
-            "regedit /s \"$regFile\"",
+            "reg import \"$regFile\"",
         "}",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"$appRoot = Split-Path $dir -Parent",
"$otherVersions = @(Get-ChildItem $appRoot -Directory | Where-Object { $_.FullName -ne $dir -and $_.Name -ne 'current' -and ($_.Name -match '^[0-9.]+$') })",
"if ($otherVersions.Count -gt 0) {",
" 'uninstall-associations', 'uninstall-context', 'uninstall-github-integration' | ForEach-Object {",
" $regFile = \"$dir\\$_.reg\"",
" if (Test-Path $regFile) {",
" regedit /s \"$regFile\"",
" }",
" }",
"}"
"$appRoot = Split-Path $dir -Parent",
"$otherVersions = @(Get-ChildItem $appRoot -Directory | Where-Object { $_.FullName -ne $dir -and $_.Name -ne 'current' -and ($_.Name -match '^[0-9.]+$') })",
"if ($otherVersions.Count -gt 0) {",
" 'uninstall-associations', 'uninstall-context', 'uninstall-github-integration' | ForEach-Object {",
" $regFile = \"$dir\\$_.reg\"",
" if (Test-Path $regFile) {",
" reg import \"$regFile\"",
" }",
" }",
"}"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bucket/vscode.json` around lines 68 - 77, The cleanup loop that builds
$regFile in the block starting with "$appRoot = Split-Path $dir -Parent" uses
"regedit /s \"$regFile\"" which is GUI-based and async; replace that call with
the synchronous CLI "reg import \"$regFile\"" to match the rest of the manifest.
Locate the loop that iterates over 'uninstall-associations',
'uninstall-context', 'uninstall-github-integration' (the $regFile variable) and
swap the regedit invocation for reg import so registry files are imported
reliably under UAC/elevation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Changes in the vscode directory caused the reg file to become invalid

1 participant