Skip to content

Replace abandoned winreg module with PowerShell for Windows PATH management#4032

Open
wojtekn wants to merge 2 commits into
trunkfrom
migrate-winreg-to-vscode-windows-registry
Open

Replace abandoned winreg module with PowerShell for Windows PATH management#4032
wojtekn wants to merge 2 commits into
trunkfrom
migrate-winreg-to-vscode-windows-registry

Conversation

@wojtekn

@wojtekn wojtekn commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Related issues

How AI was used in this PR

Claude Code investigated all winreg usage, evaluated @vscode/windows-registry as the replacement (adopted first, then dropped once it broke Windows CI — see below), and implemented the final PowerShell-based approach. All changes were reviewed by a human.

Proposed Changes

The winreg npm module is abandoned, and its latest release (1.2.5) ships a known bug — our import was pinned to 1.2.4 with a warning comment to avoid it. This removes winreg.

The Windows CLI installation manager (which reads and writes the user PATH in HKCU\Environment) now goes through PowerShell for both operations, with no registry npm module at all:

  • Read uses the raw, unexpanded value (DoNotExpandEnvironmentNames) so %VAR% entries survive a read/modify/write round-trip untouched — matching what apps/cli/commands/uninstall.ts already does.
  • Write uses [Environment]::SetEnvironmentVariable(…, 'User'), which also broadcasts WM_SETTINGCHANGE, so a freshly-opened terminal picks up a newly-installed studio command without a re-login — an improvement over the old winreg.set().

There is no user-facing behavior change to CLI install/uninstall beyond that PATH-refresh improvement.

Why not @vscode/windows-registry?

The original suggestion (and this PR's first attempt) was @vscode/windows-registry — well-maintained, from the VS Code team. Two things ruled it out:

  1. It's a native module with no prebuilt binaries. winreg was pure JavaScript and never compiled. @vscode/windows-registry runs node-gyp rebuild on install, which failed on our Windows CI (MSB8020: the ClangCL build tools cannot be found) and would add a native-toolchain requirement to every Windows build/package step.
  2. It's read-only (GetStringRegKey / GetDWORDRegKey only). It couldn't cover the PATH write anyway — that always had to be PowerShell.

Since the write was already PowerShell and the read is a one-liner there too, moving both to PowerShell removes the dependency entirely: no native build, no extra npm package, and it works anywhere PowerShell does (i.e. all Windows). This mirrors the raw-registry pattern already used in uninstall.ts.

apps/cli/commands/uninstall.ts is intentionally unchanged — it never used winreg (it runs a detached PowerShell helper after the CLI process exits, which no in-process module can do).

⚠️ Platform note: this touches Windows-only code that cannot be exercised on macOS/Linux CI. Needs a human check on a Windows build (see Testing Instructions).

Testing Instructions

Automated (any platform):

  • npm run typecheck — passes across all workspaces
  • npx eslint --fix apps/studio/src/modules/cli/lib/windows-installation-manager.ts — clean
  • npm test -- apps/studio/src/tests/index.test.ts — passes

Manual (Windows required):

  1. Build/run the app on Windows so autoInstallWindowsCliIfNeeded runs (or trigger install from the UI).
  2. Confirm …\studio\bin is added to HKCU\Environment\Path, and that any pre-existing %VAR% entries in PATH remain unexpanded.
  3. Open a new terminal and run studio --version — it should resolve without a re-login (verifies the WM_SETTINGCHANGE broadcast).
  4. Uninstall the CLI and confirm the entry is removed from HKCU\Environment\Path.

Pre-merge Checklist

  • Have you checked for TypeScript, React or other console errors?

winreg is abandoned and its 1.2.5 release has a known bug we pinned around. Switch the Windows CLI installation manager to Microsoft's maintained @vscode/windows-registry for reads, and write PATH via PowerShell SetEnvironmentVariable (which also broadcasts WM_SETTINGCHANGE so open shells refresh without a re-login).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@wpmobilebot

wpmobilebot commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

📊 Performance Test Results

Comparing 235c247 vs trunk

app-size

Metric trunk 235c247 Diff Change
App Size (Mac) 1316.83 MB 1316.79 MB 0.04 MB ⚪ 0.0%

site-editor

Metric trunk 235c247 Diff Change
load 1118 ms 1109 ms 9 ms ⚪ 0.0%

site-startup

Metric trunk 235c247 Diff Change
siteCreation 6523 ms 6499 ms 24 ms ⚪ 0.0%
siteStartup 1859 ms 1865 ms +6 ms ⚪ 0.0%

Results are median values from multiple test runs.

Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff)

@vscode/windows-registry is a native module with no prebuilt binaries, so it ran node-gyp on install and failed to compile on Windows CI. The original winreg was pure JS. Drop the native dependency entirely and read the user PATH via PowerShell (raw, unexpanded, matching uninstall.ts), sharing one PowerShell runner with the existing write. No native build step, works everywhere PowerShell does.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@wojtekn wojtekn changed the title Replace abandoned winreg module with @vscode/windows-registry Replace abandoned winreg module with PowerShell for Windows PATH management Jul 2, 2026
@wojtekn wojtekn requested review from a team and fredrikekelund July 2, 2026 08:23
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