--- title: 'Windows' description: 'Run the Stackbone CLI on Windows from WSL2 or Git Bash, and fix a tunnel that Windows will not let start.' position: 9 --- # Windows > The CLI runs on Windows from **WSL2** or **Git Bash**. WSL2 is the path we > recommend, because the CLI behaves there exactly as it does on Linux. > PowerShell and CMD stop the CLI at startup with a message that sends you to > one of the two. ## Pick a shell | Shell | Works | What to know | | -------------- | ----- | ------------------------------------------------------------------------------------------------ | | WSL2 (Ubuntu) | Yes | Same behaviour as Linux. Smart App Control and AppLocker do not check the Linux binaries it runs | | Git Bash | Yes | The CLI downloads the Windows build of `frpc`, which Windows can block. See below | | PowerShell/CMD | No | The CLI exits with `unsupported_platform` | Both working shells need Docker. With WSL2, Docker Desktop works as long as its WSL2 integration is on for your Ubuntu distribution. ## Set up WSL2
1. Install Ubuntu from PowerShell, then reboot: ```sh wsl --install -d Ubuntu ``` 2. Open the Ubuntu terminal and install Node 24 and pnpm there. The Node you installed on Windows is a different install, so do not call it from WSL2. 3. Install the CLI inside Ubuntu and sign in: ```sh pnpm add -g @stackbone/cli stackbone login ``` 4. Keep your workspace on the Linux file system (for example `~/code/my-agent`), not under `/mnt/c/`. File watching across the two file systems is slow and misses changes.
## Use Git Bash Git Bash works for every command. Two things behave differently from Linux. **Ctrl-C.** Git Bash terminals do not always give the CLI a real pseudo-terminal, so the CLI re-runs itself under `winpty` for `stackbone dev`. If `winpty` is not on your `PATH`, run `winpty stackbone dev`. See [Ctrl-C does not stop `stackbone dev` in Git Bash](/docs/cli/guides/troubleshooting#ctrl-c-does-not-stop-stackbone-dev-in-git-bash). **The tunnel binary.** `stackbone dev` always opens a tunnel, and it uses `frpc` for that. The first run downloads the Windows `frpc.exe` into `~/.cache/stackbone/bin/` and extracts it with PowerShell. Windows may refuse to run that file. The next section covers what to do. ## If Windows blocks frpc **Symptom:** `stackbone dev` stops at the tunnel stage with `The OS refused to run frpc` (`error.code` is `permission`). Running `frpc.exe` by hand gives `Permission denied`, and Defender's protection history shows nothing. **Cause:** Windows is blocking an unsigned executable. It is not the file mode and not your `PATH`. The usual reasons: | Blocker | Where it logs | | ------------------ | ----------------------------------------------- | | Mark of the Web | Nowhere. A browser tags every file it downloads | | Smart App Control | Event Viewer, under CodeIntegrity | | Microsoft Defender | Protection history, often as a HackTool | | AppLocker or WDAC | Your IT department's policy logs | **Fix:** try these in order. The error message prints the full path to the binary, so use that path in the commands. 1. If you downloaded `frpc` with a browser, remove the download tag in PowerShell: ```powershell Unblock-File "$HOME\.cache\stackbone\bin\frpc-.exe" ``` 2. Add an exclusion for the folder in Windows Security, under **Virus & threat protection** > **Manage settings** > **Exclusions**. 3. Check **App & browser control** > **Smart App Control**. Turning it off lets the binary run, but Windows may not let you turn it back on without a reinstall. Decide that one for yourself. 4. On a laptop your company manages, you usually cannot change any of these. Use WSL2 instead. `frpc` versions are not interchangeable. The CLI pins the version that matches the Stackbone relay, and it only looks for that version in the cache. If you download `frpc` by hand, take the version the error message names, or point `STACKBONE_FRPC_BIN` at your binary. See [Using a system `frpc` binary](/docs/cli/guides/local-development#using-a-system-frpc-binary). ## What's next - [Getting started](/docs/cli/guides/getting-started): from zero to a running agent. - [Local development](/docs/cli/guides/local-development): what `stackbone dev` does at each stage. - [Troubleshooting](/docs/cli/guides/troubleshooting): the other failures, keyed on `error.code`.