Tropibyte Tropibyte Download
Alpha v1.0.8.4-alpha

C Shell
for Windows.

The C shell, native to Windows. Familiar csh ergonomics, a self-contained installer, and direct access to Win32 — with no WSL, no Cygwin, and no compatibility layer.

x64 Windows 10 1809+ ~14 MB
Why CShW

A first-class Unix shell, on Windows’ own terms.

Windows developers have lived for decades with two unsatisfying options for shell work: cmd.exe, frozen in time, and WSL, which is really a separate operating system bolted on. PowerShell occupies its own niche but does not match the ergonomics of a Unix shell.

C Shell for Windows is a native Win32 implementation of csh designed for engineers who want the familiarity and discipline of a Unix shell without leaving Windows behind. It runs natively, integrates with the Windows process model, and ships with 188 bundled man pages.

Features

Built for engineers who know what they want from a shell.

No GUI launcher, no telemetry, no surprises. Just a fast, scriptable shell that does what you tell it to.

01

Native Win32, self-contained

Ships as a self-contained bundle — nothing to install separately. No WSL, no Cygwin, no Windows runtime prerequisites to chase.

02

Familiar csh syntax

Variables, aliases, history substitution, and control flow behave the way csh users expect.

03

Windows Terminal native

Registers itself as a Windows Terminal profile on install — one click to a new csh tab. ANSI escape sequences and 24-bit color throughout.

04

Tab completion & history

Completion for files, paths, and command history.

05

Scriptable

Scriptable startup file. Write scripts that integrate with the rest of your Windows tooling — with an optional VS Code extension for syntax highlighting.

06

Lightweight

Approximately twelve megabytes on disk, including bundled regex and compression. Fast startup. No background services.

Download

Free alpha preview.

CShW is in active alpha. Feedback from real users shapes what ships next — we’d like yours.

Latest release

C Shell for Windows v1.0.8.4-alpha

Installer with a desktop shortcut, Start menu integration, and Windows Terminal profile. Uninstalls cleanly. New in 1.0.8.4: a correctness release, and an upgrade worth taking — running cshw with no arguments never reached the prompt, Ctrl+C at the prompt closed the shell outright, and redirection was quietly wrong in five commands: test, xargs, repeat, tc, and any proc. A proc now honours >, pipes and chainers, $argv inside one is a real array, and cut gained -s. From 1.0.8.3: a quoted argument beginning with < or > was parsed as a redirect instead of as data, so echo ">notes.txt" truncated the file rather than printing the string. From 1.0.8.2: the shell no longer stops accepting input after you resize the window, and App Execution Aliases finally launch, so winget, wt and pwsh run from inside cshw for the first time. Failed launches now report the Windows error in words instead of a bare “failed”. From 1.0.8.1: a correctness and packaging release — fixes output crossing between concurrently running commands, adds spawn (open another cshw in a new window) and the -k switch, makes start's documented switches actually work, and signs every shipped binary. From 1.0.8.0: cshw is a server host — the tsrvd supervisor runs signed, out-of-process protocol handlers: native SMTP, POP3, and IMAP over a shared Maildir mailstore, FTP, and a real HTTP/HTTPS/CGI server (http.dll) that speaks HTTP/1.1 and HTTP/2. A new quicsrv worker serves HTTP/3 over QUIC (msquic + nghttp3) through the same static + CGI serving core, and the fetch client gains native /http2 and /http3 modes that guarantee the protocol. Carries over: concurrent pipelines from 1.0.7, bc -x exact rationals + matrices + complex, POSIX dc, the cascading settings layer, and a 22-chapter book.

Released
August 2026
Architecture
x64
Size
~15 MB
License
PolyForm Small Business 1.0.0
Download installer (.exe) Release notes
SHA-256 0f1582cf9a787e06d572ba05353c0bb755812547f5f570f12ce5a70ce33010e3
Release notes

v1.0.8.4-alpha

A correctness release. Two regressions that stopped the shell starting or kept it running, one long-standing way for redirection to go quietly wrong in five different commands, and a test suite that has stopped reporting skipped tests as passes.

What changed in 1.0.8.4

Running cshw with no arguments never reached the prompt. Windows returns the current executable’s own path when asked to parse an empty command line, and the test for “is this argument a script?” was “does this file exist” — which an .exe passes. So the shell read its own binary as a script, and because naming a script means “do not start interactively”, it printed a parse error and exited. The delimiter in that error was machine code. A binary is no longer accepted as a script, and an empty command line is no longer parsed for one.

Ctrl+C at the prompt closed the shell. The console handler routed the two onintr modes and let the default fall through as “not handled”, so Windows terminated the process and the session went with it — history, variables, jobs. Every other shell abandons the line and reprompts, which is the entire reason anyone presses it. A script with no onintr is still killable, which is what csh does.

Redirection was wrong in five commands, for one reason. A builtin that parses its own argument line was handed that line raw — redirect operators included — so test -z "" > out became a four-argument error, and xargs, repeat and tc rebuilt child command lines with the redirect still in them, making every child re-open the file the outer redirect already held. A proc call was worse: it could be nothing but the entire line, so a redirect, a pipe, a chainer or a heredoc after one was swallowed as an argument, and the heredoc form hung the shell outright. sed, awk, grep and cut were measured and were never affected.

$argv inside a proc is an array. It had been a single joined string, so $#argv was always 1, $argv[2] was always empty, and foreach a ($argv) iterated once over everything — while a script’s own $argv worked correctly the whole time. A proc also no longer inherits its caller’s positional parameters, so one called with fewer arguments than its caller stops silently seeing the rest. exit inside a proc is no longer swallowed. cut gained the documented -s, and log now refuses cmd | log FILE instead of discarding the output and leaving logging on.

The test suite stopped lying. A skipped assertion reported as a pass, so 34 of them — 24 labelled BROKEN — sat under a green banner. There are three outcomes now, the percentage is of what actually ran, and the totals name the skips. Re-measuring those 24 found that 22 described nothing wrong: either long since fixed, or a test that could not have observed what it claimed. Eleven remain, all environment-dependent.

What changed in 1.0.8.3

A quoted argument starting with < or > was treated as a redirect. The redirect parser looked only at the first character of each token and never at the token’s type, so a quoted string beginning with an angle bracket was read as a redirect operator rather than as data. The lexer had always distinguished the two; the parser simply never asked.

It failed in two ways, and the quiet one is why this shipped the same day. When the text after > was not a legal Windows filename, the open failed and you saw 'echo' failed (errno 22) with the command’s output dropped. When the text was a legal filename there was no error at all: echo ">notes.txt" truncated notes.txt, consumed the token as a redirect, and left echo with no arguments — so echo wrote its own Echo is ON status into the file it had just destroyed. Anything quoting an angle bracket was exposed: markdown blockquotes, grep "<div>" page.html, generated HTML or XML. Quoted tokens are now skipped when scanning for redirects; real redirects are unaffected.

What changed in 1.0.8.2

The shell stopped accepting input after a window resize. The keyboard helper thread gated the line editor on PeekConsoleInputW, but peeked only the first 32 records of the console input buffer. Peek never removes anything, and the only code that drains that buffer is the read loop the gate protects. So 32 or more consecutive non-key records at the head of the queue — a resize burst of focus, menu and mouse events will do it — wedged the shell permanently: everything typed afterwards sat at position 33 and later, unseen, and the buffer could only be cleared by code that only ran once the buffer was already clear. The gate now scans every pending record. Reproduced in both conhost and Windows Terminal, at 0% CPU, which is what made it look like a hang.

App Execution Aliases could not be launched. winget, wt, the Store Python stubs and every other packaged-app alias are zero-byte IO_REPARSE_TAG_APPEXECLINK reparse points. The launcher used “can I open this file and read a PE header out of it?” as a proxy for “can this be executed?”, and aliases fail both tests — they refuse ordinary read opens and carry no PE header at all — so the launch was refused before CreateProcessW ever saw them. That parse only ever produced one value, the Subsystem word that decides whether to wait for the child, so it is a hint now rather than a gate: an unreadable header means “unknown, assume console”, and the OS decides what can run. winget install Tropibyte.cshw works from inside cshw as of this release.

Win32 errors are reported on launch failure. A failed CreateProcessW used to print a bare 'name' failed. The code is now captured at the instant of failure — it was previously re-read several statements later, after intervening calls could have reset it — and decoded, so you get 'name' failed (Windows error 2: The system cannot find the file specified).

Uninitialized reads in the PE header parse. None of the three fread calls checked their return value, and the DOS header and optional-header magic were uninitialized locals, so a zero-byte or truncated file left the code branching on stack garbage and seeking to a garbage offset. Every read is checked and every buffer initialized.

What changed in 1.0.8.1

Output no longer crosses between concurrent commands. Two process-global resources were being used for per-command redirection. Command substitution closed the real stdout handle when redirecting, and Windows recycled that handle value for the next capture file — so a background command’s output could land inside an unrelated `backtick` capture, and a child process could inherit an already-closed handle. Separately, a background command using > took over the shell’s own stdout, so interactive output could vanish outright. Redirection state is now per-thread, and every shipped built-in writes through its own command’s output stream.

New: spawn. Opens another cshw in a new console window, inheriting the current directory and exported environment — with -c/-k payloads, /d, /title, /min, /max, /wait, and /here for a nested shell in the current console. The new -k switch (cmd’s /K) runs a command and then stays interactive.

Fixes. cshw -c "exit 7" returned 0 instead of 7. The start command documented /min /max /wait /b /d /i but silently ignored all six; they work now, and /wait publishes the child’s real exit code. tokenize reported failure on success.

Everything is signed. quicsrv.exe and the bundled nghttp2, msquic and nghttp3 libraries shipped unsigned in 1.0.8.0; all of them are signed here, and the portable zip now carries the native libraries it was missing — so HTTP/2 and HTTP/3 work for portable and Scoop installs too. The release build now refuses to produce an installer if any packaged binary is unsigned.

Note on the certificate. The code-signing certificate changed to correct a malformed publisher name, which previously rendered as Tropibyte\, Inc. with a stray backslash. It now reads Tropibyte, Inc. Because the certificate is new, Windows treats this as a new publisher and SmartScreen reputation starts over — you may see a warning on first run even though the installer is signed.

→ Previous releases (1.0.8.0 back through 1.0.1)

What works

Shell fundamentals. csh/tcsh-flavored control flow (if/while/foreach/loop/for/switch) with optional then on every header. Procedures with locals and $result. Real arrays and hashes. Chainers (;, &&, ||, and, or, xor, nor, nand). Stderr redirection (2>, 2>>, 2>&1). Regex match (=~ / !~). Persistent history with bang-recall and Ctrl-R reverse search.

Daily-driver commands. Full text-tool suite (grep with PCRE2, sed, awk, sort -t/-k, uniq, cut, tr, wc, head, tail -f). File operations including find with size/mtime/type filters. Job control. genai (OpenAI, Anthropic, Azure, Ollama, LM Studio). Networking primitives. Browse all 225 in the full command reference →

Windows-native. Real concurrency (coroutines plus mutex, event, semaphore, barrier, channel). Plugin DLLs in C/C++. Direct Win32 from the shell (rundllproc, winapi, dllimport). Runs your existing .bat/.cmd scripts through cmd.exe and .ps1 scripts through PowerShell — cshw dispatches them to the right interpreter, it doesn’t reinterpret them.

What’s flaky

It’s alpha. Expect rough edges. Some commands have feature gaps relative to GNU equivalents (e.g., awk is a subset of full POSIX awk; sort -k accepts a single field rather than ranges). The Win32 calling-convention surface of rundllproc is generally x64 fastcall; mismatched signatures are still UB. Found something broken? Email bugs@tropibyte.com.

Trust model

cshw is a developer/admin shell. Plugins are native code; rundllproc calls real Win32; scripts aren’t sandboxed. The trust model is identical to running any .exe: you load it, you ran it, you trust it. No auto-discovery of plugins from the internet, no driver-level code, no hidden privilege escalation.

Verifying the download

The SHA-256 of the installer is shown above. Verify in PowerShell with Get-FileHash cshw-setup-1.0.8.4.exe -Algorithm SHA256. If the hash doesn’t match, don’t run the installer.

Roadmap

What’s next.

CShW ships incrementally. Here’s the work currently on the path to beta.

Now · Alpha

Core shell stability

Hardening the core interpreter, expanding the test suite, and addressing alpha feedback.

Next

ARM64 builds

Native binaries for Windows on ARM, alongside the existing x64 release.

Next

Configuration profiles

Per-project shell configuration with explicit precedence and reload semantics.

Beta · Q3 2026

Public beta

Wider release with installer signing chain, automatic updates, and a published EULA.