microsoft / microsoft/vscode-python-environments

CMD shell startup integration overwrites user's existing `HKCU\...\Command Processor\AutoRun` registry value

Open
#1,583 0 comments 0 reactions 1 assignee Claimed by @anthonykim1 View on GitHub
area-terminal area-terminal-cmd bug important needs PR
Dominant language
TypeScript
Stars
138
Forks
62
Avg merge
1d 4h
Merged PRs (30d)
35

Description

## Problem

[`setupRegistryAutoRun`](src/features/terminal/shells/cmd/cmdStartup.ts) writes our batch-file path into `HKCU\Software\Microsoft\Command Processor\AutoRun` with `reg add ... /f`, which **completely overwrites** any existing AutoRun value the user (or another tool) had configured.

CMD AutoRun is a chainable command string — tools that need to hook into CMD startup conventionally append with `&` rather than overwrite. Our code does not do this.

## Symptoms

A user who relies on a personal AutoRun (a common pattern: pointing AutoRun at a `.cmd` startup file that adds tools to `PATH`, sets aliases, etc.) will see those customizations stop working after PEM activates the CMD shell integration. The most visible failure mode is "tool X disappears from `PATH` in the VS Code terminal but works elsewhere," because the PATH-additions in their AutoRun are no longer running.

This matches a recent marketplace review describing exactly this shape — `PATH` losing entries and a CLI tool (ripgrep) becoming unfindable from the VS Code terminal specifically.

## Affected code

- [`setupRegistryAutoRun`](src/features/terminal/shells/cmd/cmdStartup.ts) — overwrites with `/f`.
- [`setupCmdStartup`](src/features/terminal/shells/cmd/cmdStartup.ts) — calls `getExistingAutoRun()` to check whether *our* path is already present, but if any other content is there it still overwrites.
- [`removeCmdStartup`](src/features/terminal/shells/cmd/cmdStartup.ts) — explicitly comments *"We deliberately DO NOT remove the main batch file or registry AutoRun setting"*. So once we've overwritten the user's AutoRun, we never restore it on disable/uninstall either.

## Fix direction

1. **Chain instead of overwrite.** When `getExistingAutoRun()` returns non-empty content that doesn't already include our path, prepend the existing string and join with `&`: `${existingAutoRun} & if exist "${mainBatchFile}" call "${mainBatchFile}"`.
2. **Surgically remove on teardown.** In `removeCmdStartup`, locate our segment in the AutoRun value and strip just that segment (preserving the user's prior content), rather than leaving the registry pointing at our (possibly missing) batch file.
3. **Unit-test the merge/strip logic** as pure string transformations — no need to mock the registry.

## Acceptance criteria

- [ ] Setting up CMD shell activation when AutoRun already has user content preserves that content; the new AutoRun is `${existing} & ${ours}`.
- [ ] Setting up CMD shell activation a second time when AutoRun already contains our line is idempotent (no duplication).
- [ ] Tearing down (disable / uninstall) removes only our segment from AutoRun and restores the user's prior content. If we were the only content, the AutoRun key returns to its pre-PEM state (cleared, or restored to the empty string we started with).
- [ ] Unit tests cover: empty AutoRun, AutoRun with only our content, AutoRun with only user content, AutoRun with our content followed by user content, AutoRun with user content followed by ours, AutoRun with our content sandwiched in the middle.

## Notes

- Risk is low. The chained-AutoRun pattern is well-established CMD convention.
- This issue stays narrowly scoped to the registry overwrite. Adjacent concerns (e.g. whether to write to AutoRun at all, vs. relying on `clink` / VS Code's shell integration) are out of scope here.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.