I'm Koen. I've been writing code for close to three decades now, running my own shop out of Los Angeles, splitting my time between client work and my own products. This post is about a fight I had with Claude Desktop on Windows over the past week — one that started with a boring-looking error dialog and ended with me digging through kernel object reference counts and AppX container internals just to get my chat app to open. I'm writing it up because I burned a lot of hours scattered across a dozen half-finished GitHub issues before the picture came together, and I figured someone else is about to do the same thing. Hopefully this saves you a few of those hours.
Here's the short version up front, because I hate articles that make you scroll to the bottom for the payoff: this is an unresolved bug in how Claude Desktop packages itself for Windows via MSIX, and there's no real fix from Anthropic's side yet. What actually worked for me was dropping the MSIX build entirely and switching to the older Squirrel-based .exe installer that Anthropic still ships in parallel. Everything below is the messy path that got me there, dead ends included.
A quick word on how I run my machine
My work PC never sleeps and never reboots unless I force it. That's not laziness — it's deliberate. I've got a pile of terminals, editors, background services, and long-running SSH sessions that I don't want to lose track of, and Windows' habit of deciding on its own that *now* is a great time to restart to finish an update is, in my book, one of the worst design decisions in consumer software. So auto-restart is disabled on this box, and Claude Desktop just lives there permanently, same as everything else.
That habit matters for this story, because it's exactly why "just reboot" was never an acceptable answer for me. Rebooting isn't free — it means manually clawing back a dozen sessions and pieces of context I was mid-flight on. After thirty years of doing this, the idea that keeping a piece of software functional requires a periodic reboot ritual feels backwards. Software should be predictable. You shouldn't need a superstition to keep it running.
How I first noticed something was wrong
The first time it happened, I walked up to my desk in the morning and Claude Desktop just... wasn't there. It had closed itself sometime overnight, almost certainly during a background auto-update. I clicked the icon to bring it back and got hit with a Windows system dialog instead:
Another program is currently using this file.
C:\Program Files\WindowsApps\Claude_1.37937.3.0_...
One OK button, and that was it — the app refused to launch. My gut reaction, after years of chasing this exact class of bug, was "something's still holding a handle open." Standard playbook:
- Kill every Claude-related process in Task Manager
- Try launching again
Didn't work. Same dialog. Since the error message actually named the path, I figured I'd go take a look myself and see what was supposedly locked. I opened File Explorer, navigated to C:\Program Files, and — no WindowsApps folder in sight. I knew it had to be hidden, so I just typed the path straight into the address bar and hit enter.
That's where things got weird. File Explorer flat-out told me I didn't have permission to open it. I sat there for a second, genuinely thrown off — I'm on an administrator account, top-level access on my own machine, and I couldn't even *look inside* a stock Windows folder. That didn't square with anything I'd internalized over thirty years of doing this professionally. Admin is supposed to mean admin.
So I went and looked into what WindowsApps actually is, and it turns out it's a lot weirder than I expected. That folder holds every app installed through the Microsoft Store / AppX pipeline, and it's not owned by the Administrators group at all — it's owned by a special system account called TrustedInstaller, which sits above local admin in the privilege hierarchy. By default, even an admin account gets almost no access to it. Microsoft locked it down that way specifically to stop users (or malware) from tampering with Store app packages and breaking their integrity checks. To actually get in, you have to manually go into Properties → Security → Advanced and reassign ownership to yourself — and the community consensus is pretty clear that you should switch ownership back to TrustedInstaller afterward, because messing with files while you own that folder can quietly break Store apps in ways that are annoying to undo.
That was my first real signal that something bigger was going on: Claude was living inside a specially fenced-off corner of the filesystem that even I, as admin, wasn't meant to casually poke around in. This wasn't the simple "app lives in Program Files" relationship I'd taken for granted with every other Win32 program for decades. There was clearly a whole layer of machinery underneath that I didn't understand yet — and that's what sent me down the MSIX/AppX rabbit hole later.
What I found online at that point was mostly "just restart your PC," and given that I really didn't want to blow away a desktop full of running work just to open a chat app, I poked around a bit more on my own first, came up empty, and — running out of patience — caved and rebooted. The error vanished. I chalked it up to a one-off fluke and moved on.
It came back — and this time I wasn't going to reboot my way out of it
A few days later, same story: walked over in the morning, Claude had quietly closed itself overnight, same error dialog waiting for me. That's when it clicked that if this thing keeps coming back, "reboot" was never a fix — it was a band-aid with a real cost attached. Given how I run this machine, treating a periodic reboot as routine maintenance for one app just wasn't something I was willing to accept. That's the point where I stopped treating this as a one-off annoyance and actually sat down to trace it to the root.
Digging in, layer by layer
Layer one: assuming it was a stale MSIX file lock
The first thing I confirmed was that Claude Desktop on Windows ships as an MSIX package — the file path in the error, C:\Program Files\WindowsApps\Claude_..., matches that exactly. MSIX is Microsoft's modern app packaging format, and in theory an update has to fully quit the old version before it can swap files. Sure enough, there's a GitHub issue in anthropics/claude-code (#66497) describing exactly this — clicking "Relaunch to Update" dying with this same dialog, attributed to the old process not releasing its file lock in time.
Following that lead, I went nuclear on the processes from an elevated PowerShell prompt:
Get-Process | Where-Object { $_.ProcessName -match "claude|cowork" } | Stop-Process -Force
No change. And here's the detail that tipped me off that the "file lock" theory was wrong: Task Manager showed nothing with an open handle into that install directory. Nothing was locking that file. The error message was lying to me.
Layer two: the real failure is happening in the AppX container layer, not the filesystem
Digging further turned up some much more thorough issues (#53247, #61635, #73107) where other developers had gone as far as running Sysinternals' handle.exe and Process Explorer to prove, definitively, that no user-mode process held a lock on that file at all. The actual failure was happening in Windows' AppX / Desktop Bridge container layer. Event Viewer showed the real story:
Event ID 215: 0x80070020: cannot create the Desktop AppX container for package Claude_<version>_x64__pzs8sxrjxfjjc due to an error converting the job
Event ID 208: 0x80070020: cannot create the process for package ... due to an error setting up the runtime
0x80070020 is ERROR_SHARING_VIOLATION, and it's surfacing during the Job Object → Silo conversion — the step where Windows spins up an isolated container for the app to run inside, which is standard practice for anything packaged via MSIX/Desktop Bridge. That container creation was failing, and Windows was slapping the generic "another program is using this file" text on top of it — which is flat-out wrong, and actively misleading. My whole initial theory of a stale file lock was chasing the wrong layer entirely.
This was probably the single most useful thing I took away from the whole ordeal: the error text a system dialog shows you is not guaranteed to reflect where the failure actually happened, especially once you're several layers of abstraction deep (AppX container → Win32 error code → generic user-facing string). Real root-causing means reading the raw Event IDs in Event Viewer, not the dialog text.
Layer three: kernel reference counts, and who's pinning the object open
Going one level deeper, issue #61635 laid out the full chain, and this is the part that genuinely taught me something new after thirty years of doing this:
Windows kernel objects — Job Objects included — are reference-counted. As long as *any* process or service still holds a handle to one, it stays alive, even after it's vanished from the visible Object Manager namespace. Here's what was actually happening on my machine:
- Claude's app container gets a deterministic name, something like
Container_Claude_<version>_<user SID> - At some point I'd triggered a UAC elevation prompt from inside Claude, and Windows' AppInfo (Application Information) service — the thing that handles elevation requests — opened a handle to that container's Job object
- When Claude exited, or got updated to a new version, AppInfo never let go of that handle. A textbook handle leak.
- That zombie object stayed alive in the kernel, propped up by that one lingering AppInfo reference, still occupying its naming slot
- The next time Claude tried to spin up a fresh container with the same name, it collided with the half-dead old one, and boom —
ERROR_SHARING_VIOLATION
Rebooting works because it force-kills every process and service on the box, including AppInfo, which zeroes out the reference count and finally lets the kernel actually tear the zombie object down. But as I said, rebooting was off the table for me — I needed something else.
Trying to sidestep the reboot — a few dead ends
Once I understood the mechanism, I tried a few things, all with the same constraint: no reboot, no logoff.
Attempt 1: restart the AppInfo service directly. Since it's the one holding the leaked handle, restarting just that service should, in theory, have the same cleanup effect without touching my login session:
Restart-Service -Name Appinfo -Force
Result:
Restart-Service : Service 'Application Information (Appinfo)' failed to stop.
Turns out Windows deliberately won't let you manually stop AppInfo. It's the gatekeeper that lets everything else request elevation — if you could stop it on a whim, you'd hit a deadlock where stopping it requires elevation, which requires it. There are horror-story forum threads of people who accidentally disabled it and locked themselves out of every admin-level function on their PC until they booted into Safe Mode to undo it. Dead end, and not one I was going to force my way past.
Attempt 2: restart AppXSVC / ClipSVC — the more general AppX deployment services:
Restart-Service -Name AppXSVC -Force
Restart-Service -Name ClipSVC -Force
These actually ran, but didn't fix anything — because the root cause here was Claude's own launch/crash path not cleaning up its container state, not those two services being broken system-wide. Every other AppX app on the box (Notepad, OneDrive sync, Store apps) was creating containers fine in the same time window, which rules out a system-level service failure.
Attempt 3: sign out of Windows instead of a full reboot — some community reports claimed logging off has the same cleanup effect as a reboot, since a lot of session-scoped state gets torn down either way. For me, given that I've got a desktop full of running windows and processes, signing out carries the same recovery cost as a reboot. Not a real option, so I dropped it.
At that point I had my answer: this is a bug Anthropic needs to fix in code — the launch/crash path isn't reliably releasing its container handle — and there's no safe way to work around it purely at the OS level. The core GitHub issue (#53247) is still open as I'm writing this.
Changing strategy: if MSIX's container model is the problem, stop using MSIX
Once that clicked, I stopped trying to fight the bug on its own turf and looked for an install path that never triggers this container machinery in the first place — fix it at the source instead of firefighting every time it flares up.
Turns out Claude Desktop on Windows actually ships through two parallel channels:
- .msix — the "modern" install path introduced alongside Cowork in February 2026, which brings Cowork support but also inherits this whole container mechanism and its bugs
- .exe (Squirrel framework) — the older, more traditional install path, which skips AppX containers entirely but doesn't support Cowork
I don't use Cowork — Claude Code is my daily driver for dev work — and the two features are independent of each other, so switching to the Squirrel build cost me nothing functionally.
First attempt: winget, which just... sat there
winget install --id Anthropic.Claude -e
Ran for a long time with zero output. My guess was a hidden agreement prompt swallowing the input, so I retried with the flags to skip it:
winget install --id Anthropic.Claude -e --accept-package-agreements --accept-source-agreements
Still nothing. I tried winget source reset --force, checked for stuck winget processes, checked for pending Windows updates blocking it — none of it moved the needle. Gave up on winget and went straight to the source.
Second attempt: the direct download link, blocked by a Cloudflare challenge
I found Anthropic's official redirect link for the Squirrel build:
https://claude.ai/api/desktop/win32/x64/exe/latest/redirect
Tried pulling it straight from the command line:
Invoke-WebRequest -Uri "https://claude.ai/api/desktop/win32/x64/exe/latest/redirect" -OutFile "$env:USERPROFILE\Downloads\ClaudeSetup.exe"
What came back wasn't an installer — it was a chunk of HTML and JavaScript from a Cloudflare bot-check challenge page. A command-line tool with no JS engine has no shot at clearing that.
What actually worked: just open the link in a real browser
Dropped the command-line approach and pasted the link straight into my browser's address bar instead. It cleared the human-verification check normally and kicked off the download — a real installer this time. Double-clicked it, and it installed silently, with zero UAC elevation prompt the entire time — which on its own told me this was genuinely taking the older, non-containerized Squirrel path.
Confirmed it landed correctly:
Get-ChildItem "$env:LOCALAPPDATA" -Filter "*claude*" -ErrorAction SilentlyContinue
Get-ChildItem "$env:LOCALAPPDATA" -Filter "*anthropic*" -ErrorAction SilentlyContinue
Sure enough, it was sitting under %LOCALAPPDATA%\AnthropicClaude, laid out exactly like a Squirrel install should be.
It finally worked — and this time, without a reboot
With the Squirrel build in place, Claude Desktop opened up cleanly. No reboot involved this time — I'd actually solved the problem at its root instead of stomping it back down for a few days. For someone who runs their machine the way I do — always on, always full of running work — that's the difference between a real fix and another lucky roll of the dice.
Signed in, and my regular chat history was intact, exactly as expected — that data lives server-side, tied to my account, completely independent of what's installed locally.
Opening up my Claude Code session history, though, gave me this:
Can't reach your computer
It may be asleep or offline. This session will reconnect when it's back.
Remote Control host unreachable (computer_unreachable)
This is Claude Code's Remote Control feature — it lets you pick up a local coding session from your phone or a browser, but only as long as the actual process on your machine stays alive. Between the uninstall, the reinstall, and that one reluctant reboot earlier in the week, the local process backing that session had been killed and restarted more times than I could count. The conversation history itself was fine — nothing lost there — but the live connection acting as the "remote host" was permanently gone. Not a network hiccup. There was simply no live process left to reach.
To pick that back up, I'd need to go back to the machine and run claude --resume to reattach to the old session, then fire off /remote-control again inside the resumed session to stand up a fresh remote link. Consider this the one cost of this whole exercise I couldn't fully dodge — worth knowing about going in.
If you're hitting this too
If you're staring at "another program is currently using this file" pointing at C:\Program Files\WindowsApps\Claude_..., here's the order I'd try things in:
- Don't jump straight to a reboot. Kill every Claude/cowork-related process and try relaunching first — it's a long shot, but occasionally it's enough.
- If you'd recently triggered a UAC prompt inside Claude, check Task Manager's Details tab for any orphaned elevated child processes hanging around. Killing the right one can clear this without touching your session at all.
- If you don't need Cowork — just Claude Code or regular chat — switching to the Squirrel build is the cleanest fix available right now: uninstall the MSIX version, then open
https://claude.ai/api/desktop/win32/x64/exe/latest/redirectin an actual browser (not from the command line) and install manually. - Back up
%USERPROFILE%\.claude\projects\before you touch anything. It shouldn't be affected by a reinstall, but there's no reason not to have a copy anyway. - Set your expectations accordingly — this is a bug on Anthropic's end, not something wrong with your setup, and there's no permanent fix available on your machine. All you can really do is route around what triggers it.
- If you run your machine like I do — always on, allergic to unplanned restarts — this whole story is basically the argument for why chasing the root cause is worth the time. Rebooting your way through a recurring bug was never a real fix; it's just deferred cost.
- If you rely on Remote Control, know that this kind of system-level churn (reboots, reinstalls) will sever any live remote session.
claude --resumelocally gets you back on track — your data isn't going anywhere.
After thirty years of doing this, the thing that gets me every time isn't the difficulty of the fix itself — it's when the system's own error message is simply wrong. You have to disprove the surface-level story before you can find the layer actually worth digging into. This one took me from "file is locked" all the way down to kernel reference counting, which is a longer detour than I expected, but every layer down had real, verifiable technical footing behind it. That's exactly why I bothered writing it up — so the next person hitting this can skip the wrong turns I took, and maybe skip a reboot or two along the way.