Skip to content

fix: surface MS Store CLI shadowing on Windows (#60) - #63

Open
cushycush wants to merge 1 commit into
mainfrom
fix/windows-store-collision-issue-60
Open

cushycush wants to merge 1 commit into
mainfrom
fix/windows-store-collision-issue-60

Conversation

@cushycush

Copy link
Copy Markdown
Owner

What this does

On Windows, %LocalAppData%\Microsoft\WindowsApps\store.exe (the Microsoft Store CLI shim) sits ahead of ~\go\bin on PATH and wins command resolution. After go install, typing store apply runs the Microsoft shim instead of this tool, and the user gets no signal that anything is wrong. @OliStarCooke reported this in #60 and shared a PowerShell $PROFILE wrapper that bypasses PATH lookup. This PR makes that fix discoverable.

I considered renaming the binary, shipping a Windows-only dotstore alias, publishing to Scoop, and a few other options. The reporter himself said "more of a heads up kind of thing," and a Scoop or rename is a much heavier intervention for what is, today, a small Windows user base. So this PR keeps the binary name and adds two guidance layers.

How it works

Layer 1: README. A new Installation subsection documents the collision, shows where.exe store so the reader can confirm the shim is winning, and gives the PowerShell $PROFILE snippet:

function store {
  & "$HOME\go\bin\store.exe" @args
}

It also explains why the function is enough (PowerShell function dispatch beats PATH lookup, so the shim never wins for typed store invocations).

Layer 2: runtime hint. checkWindowsShimCollision runs at the top of main(). On Windows only, it shells out to where.exe store, parses the result, and if the first match is a WindowsApps path that is not this binary, prints the same hint to stderr. A marker file at %AppData%\store\windows-shim-hint-shown suppresses subsequent prints; deleting it brings the hint back. No-op on Linux and macOS, gated entirely by runtime.GOOS == "windows" so the cost on other platforms is one branch.

The case where this layer actually helps is when a user invokes the binary by full path (~\go\bin\store.exe apply) after the shim has confused them — they get the wrapper snippet right where they're working.

Tests

shimShadowsBinary is the pure parser, split out so it stays testable on every platform. Nine cases cover shim-first, our-binary-first, only-shim, only-our-binary, empty input, case-insensitive matching on both the exe path and the WindowsApps segment, third-party store.exe outside WindowsApps (does not trigger), and leading blank lines. The orchestration around it (filesystem marker, where.exe, os.Executable) only runs on Windows so I haven't covered those paths from a Linux runner; the marker logic is small and the rest is stdlib.

Caveats

  • The runtime hint only fires when the real binary actually executes. If the user types store apply and PATH resolves to the shim, the shim runs and our code never sees the invocation. The README is the catch for that case.
  • The marker file is per-user, not per-shell. If the user has multiple Windows accounts they would each see the hint once.
  • I did not add a store doctor check for the same condition, since the reporter's own assessment was that this is a heads-up rather than a recurring health concern. Easy to add later if the issue resurfaces.

Test plan

  • go build ./... && go vet ./... && go test ./... clean on Linux
  • Unit tests pass for the parser across the nine cases listed above
  • Manual verification on a Windows machine with the shim present (I do not have one; @OliStarCooke or anyone on Windows can confirm the hint fires once and stays quiet thereafter)

On Windows, %LocalAppData%\Microsoft\WindowsApps\store.exe (the
Microsoft Store CLI shim) sits ahead of ~\go\bin on PATH and wins
command resolution. After go install, typing `store apply` runs the
shim instead of this tool. The reporter's own workaround was a
PowerShell $PROFILE function that bypasses PATH lookup.

This adds two layers of guidance:

1. A README install note documents the shim collision and the
   PowerShell wrapper so anyone reading the install docs sees the
   fix.

2. checkWindowsShimCollision runs at startup and, when it detects
   the shim ahead of this binary on PATH, prints the same hint to
   stderr once. A marker under the user's config dir suppresses
   future prints. No-op on non-Windows.

The pure parser (shimShadowsBinary) is split out and tested across
shim-first, our-binary-first, blank-input, third-party-store.exe,
and case-insensitive cases. Closes #60.
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.

1 participant