KillerShell Download
The Tech of

A look under the hood at how KillerShell walks a folder tree, matches filenames, reads inside files, moves them around, hosts a shell and edits text, all without ever building an index.

Tech stack

KillerShell is a native Windows app. There is no Electron, no browser engine, no runtime to install, and no background service. Everything below ships inside a single .exe that runs on its own:

ComponentDetail
UIWPF on .NET Framework 4.8 (net48), x64, custom window chrome
Search engineA parallel engine: one walker feeds a worker per CPU core, and results are pushed to the UI in batches, cancelable at any time
File walkA breadth-first walk built on Directory.EnumerateFiles, yielding files one at a time and skipping folders it cannot read
Content readA buffered FileStream and StreamReader that reads each file line by line, with a null-byte check to skip binaries
ExportA self-contained HTML report or CSV, written directly from the result set, no libraries required
TerminalA hosted console: the shell you picked runs as a real child process and its output is drawn by the app, with the working directory tracked from the shell's own OSC 7 reports
EditorAvalonEdit (MIT), vendored as source and compiled into the exe rather than shipped as a DLL, so the app is still one file
PackagingSingle executable. Run it portable, or install it for your account or for every user on the PC.

Install & data

KillerShell is a single .exe. Put it anywhere and run it as is, or use the built-in installer, which copies the app in, adds a Start Menu shortcut, and registers a normal Windows uninstall entry. Installing for your own account needs no admin rights; installing for every user on the PC asks for permission once and puts it in Program Files, which is the same machine-wide install /silent performs for winget, Chocolatey and RMM tools. Either way there is no .NET runtime and nothing else to install.

Your settings, such as the last folder you searched and your theme choice, are kept in the registry under your own account rather than in a file next to the .exe, so the program stays a clean single file you can move around. When you run it from outside its installed location, a PORTABLE badge appears so you know which copy you are using.

The search pipeline

A search is one continuous pass over a folder tree. You give KillerShell a starting folder and one or more search terms, then it walks every file underneath and tests each one against your terms as it goes. There is no separate indexing step and nothing is stored between runs, so the first search on a folder is just as fast as the tenth.

Each term is either a name term, matched against the filename, or a text term, matched against the contents of the file. You can mix as many of each as you like in a single pass, and optional include and exclude filters narrow which files are looked at in the first place. A piped tab - search within results - runs this same pass over a snapshot of another tab's result list instead of walking a folder.

folder + terms + filters what you type in and press search walk the tree, one file at a time streamed, never listed up front; unreadable folders skipped filters: exclude, then include files outside the scope are dropped here name terms wildcard match on the filename text terms read the file line by line, skip if it looks binary results, batched every ~150 ms stream into the list as they are found; cancel any time
The whole search is one streamed pass. Files flow through the filters, each surviving file is tested against every term, and any file with at least one hit is added to the next batch pushed to the results list. Because results are batched about every 150 milliseconds, the list fills in smoothly instead of freezing until the end.

Matching files

Every file that clears the filters is tested against each of your terms. The two kinds of term work differently.

Name terms: wildcards

A name term is a wildcard pattern tested against the filename. An asterisk stands for any run of characters and a question mark stands for a single character, the same shorthand Windows itself uses. The pattern is turned into an anchored regular expression once, so *.log matches any name ending in ".log" and report_?.txt matches "report_1.txt" but not "report_final.txt".

*.log // any name ending in .log
report_*.xlsx // report_ then anything, then .xlsx
?.tmp // a single character, then .tmp

Text terms: reading inside files

A text term looks for a run of characters inside the file. Before reading, KillerShell checks the first few kilobytes for a null byte, which almost never appears in text but is common in programs, images, and archives. If it finds one, the file is treated as binary and skipped, so a content search does not waste time scanning a photo or an .exe.

Files that pass that check are read one line at a time through a buffered reader that also honors a byte-order mark if the file has one. The whole file is never loaded into memory at once, so a multi-gigabyte log is no heavier to search than a small note. Each line that contains the term is recorded with its line number and its text, trimmed of surrounding whitespace - up to the first 100 matched lines per file, so one pathological file cannot flood the results.

Filters & multiple terms

Include and exclude filters decide which files are looked at before any term is tested. Both take a list of patterns separated by semicolons, trimmed of spaces. Alongside them, filter rows narrow the pass by extension, date modified, or file size; a file must clear every active filter before any term is tested.

  • Include patterns are wildcards tested against the filename. When any include is set, a file has to match at least one of them to be searched at all, so *.txt;*.log limits the pass to text and log files.
  • Exclude patterns work two ways at once. A pattern that matches a folder name anywhere in the path, such as bin, obj, or node_modules, drops everything under that folder. The same pattern is also tested as a wildcard against the filename, so *.min.js skips minified files wherever they sit.

Every term you add runs in the same single pass over the tree, so searching for three names and two phrases costs one walk of the folder, not five. Each term keeps its own running match count, shown as a small badge next to it, so you can see at a glance which patterns are hitting and which are not.

Streaming, memory, and cancellation

The reason KillerShell can start on a huge folder like your whole user profile without a long wait is that it never builds a list of the tree up front. The walk yields one file at a time and the search reacts to each file as it arrives, so work begins on the first file instead of after the last. Folders it is not allowed to read are quietly stepped over rather than stopping the search.

The search itself runs on background workers, one per CPU core, which keeps the window responsive and lets a long search be canceled the moment you ask. Results are collected and handed to the UI in batches on a fixed timer, about once every 150 milliseconds, along with the running file count and the file currently being read. That single, gentle pace is what stops a fast search from flooding the interface with thousands of tiny updates.

Memory stays flat because nothing large is ever held at once. Files are read through fixed 64 KB buffers, content is streamed line by line, and only the lines that actually matched are kept. A search across hundreds of thousands of files uses about the same memory as a search across a handful.

Export

Any result set can be written to a self-contained HTML report: the matched files, the matched lines with their line numbers, and the search that produced them. The report is a single file that opens in any browser with no dependencies, which makes it easy to attach to a ticket or keep as a record of what was found and where. A CSV export sits alongside it for spreadsheets.

File operations

Copy and move run on a background worker with a progress card showing the current file and a real byte count, so a large copy never freezes the window. A name collision at the destination stops the worker and asks, showing both files' size and date, with Replace, Skip or Keep both and a "do the same for the rest" checkbox. The worker genuinely waits on that answer rather than copying ahead of it, so nothing is overwritten while the question is still on screen.

A move within one volume is performed as a rename, which is a directory-entry change rather than a data copy, so it is instant whatever the size. Across volumes it copies first and deletes the source only once the copy has landed. Sending to the Recycle Bin is the one operation that goes through the Windows shell, because there is no other way in, and that is also what puts it on Explorer's undo stack, so Ctrl+Z in Explorer brings the files back.

Drops onto a browsed folder follow Explorer's modifier rules exactly: Shift moves, Ctrl copies, and neither means move within a drive and copy across drives. Files already sitting in the target folder are ignored rather than raising a collision with themselves, and a folder cannot be dropped into its own child.

The terminal

A shell tab starts the host you picked as an ordinary child process with the folder you were looking at as its working directory, then draws its output itself. Nothing about the shell is emulated or wrapped: the process is a real PowerShell, Windows PowerShell or cmd.exe, so your modules, aliases and profile all behave the way they do anywhere else.

The working directory shown on the shell's toolbar comes from the shell reporting it, not from KillerShell guessing. Shells emit an OSC 7 escape sequence naming their current directory, which is parsed out of the stream, so the readout stays correct through a cd, a script or a pushd, and clicking it opens that exact folder as a browsing tab.

The $PROFILE path is obtained by launching the shell binary with -NoProfile -NonInteractive and asking it for $PROFILE.CurrentUserCurrentHost, then validating that what came back is a single rooted path ending in .ps1. Assuming Documents\PowerShell\ instead would be wrong on any machine where OneDrive Known Folder Move has redirected Documents, which on a managed fleet is most of them, and the assumed path is a file the shell will never load.

The shipped prompt draws powerline separators, a git branch mark and a chevron. No monospaced font Windows ships has any of them, so the exe carries KillerGlyphs.ttf: 26 glyphs, 2,928 bytes, subset from Terminess Nerd Font under the SIL OFL. The renderer asks the font you chose for a glyph and only falls back to that face for the codepoints it does not have, stretching the fallback glyph to the chosen face's cell width so a separator still butts against the next cell. Your font choice is untouched; it just stops being able to fail on those characters. A whole Nerd Font would have cost 2.6 MB, almost all of it icons no prompt draws.

The editor

The editor is AvalonEdit, the component behind SharpDevelop, vendored into the repository as source and compiled into the exe rather than referenced as a DLL. That keeps KillerShell a single portable file and costs about 640 KB. The vendored tree was audited to zero compiler warnings on the way in, without suppressing any of them.

Encoding is decided by inspecting the file's bytes, not by the editor's own loader, which hands back a UTF-8 encoding that writes a byte-order mark. Left alone, a plain .txt or .bat would silently grow three bytes at the front the first time it was saved. A BOM that is present is kept, a BOM that is absent stays absent, and bytes that do not decode as UTF-8 fall back to the system ANSI codepage rather than being replaced with U+FFFD. Both the encoding and the line ending are shown under the document, because whether PowerShell 5.1 will read a script depends on both and neither is visible in the text.

Syntax definitions for .bat, .reg, .ini, .yaml, .log and .csv are hand-written and embedded, since AvalonEdit ships none of them. Rather than maintain a repainted copy of every definition for each of the six themes, the shipped colors are run through the same contrast guard the terminal uses: hue is preserved and only lightness is moved, far enough to clear a readable contrast ratio against whatever the current background is. The original color is remembered per definition, so switching themes repeatedly cannot ratchet a color away from what its author intended.

Themes & languages

KillerShell ships with six themes (Dark, Light, Black, Blood, Greed, and Cyanotic), each with its own set of accent colors, all switchable live from the toolbar. The interface is localized in ten languages: English, Spanish, German, French, Turkish, Czech, Japanese, Chinese in both Traditional and Simplified, and Bengali. Every visible string is resolved through a resource lookup, so switching language reflows the whole window with no restart.

The whole app also scales. Rolling the wheel over the title-bar wordmark drives a layout transform on the content host, roughly 2% a notch between 70% and 250%, remembered between runs. Because it is a layout transform rather than a render transform, text reflows and re-rasterizes at the new size instead of being stretched as a bitmap, and the title bar and footer stay a fixed size so the wordmark never moves out from under the pointer.

Glossary

Plain-language definitions of the terms used on this page, in alphabetical order.

TermWhat it means
Binary fileA file that holds data rather than readable text, such as a program, image, or archive. KillerShell detects these by a null byte near the start and skips them during a content search.
Byte-order markA few bytes at the very start of a text file that state how its characters are encoded. KillerShell reads it so unusual encodings are handled correctly.
Case sensitivityWhether uppercase and lowercase letters are treated as different. The default is off, so "Error" and "error" both match; a toggle turns it on for both names and content.
Content searchSearching inside the text of files for a run of characters, as opposed to searching their names.
Include / exclude filterSemicolon-separated patterns that decide which files are searched. Include narrows the pass to matching files; exclude drops matching files and folders.
Font fallbackDrawing a character from a second font when the chosen one has no glyph for it. KillerShell does this per character in the terminal, so a prompt's powerline and git symbols render whatever font you picked.
IndexA prebuilt catalog of files that some search tools rely on. KillerShell does not use one, which is why it needs no setup and no waiting for a catalog to build.
Line numberThe position of a matched line within its file, counted from the top, recorded so you can jump straight to it.
OSC 7A short escape sequence a shell emits to announce its current directory. KillerShell reads it, which is why the folder shown on a shell tab's toolbar stays right through a cd or a script.
PortableAble to run from anywhere without being installed. KillerShell runs as a loose .exe and shows a PORTABLE badge when it does.
Regular expressionA precise pattern-matching notation. KillerShell converts each wildcard filename pattern into one internally to test names quickly.
StreamingReading a file or a folder tree a small piece at a time instead of loading it whole, which keeps memory low no matter the size.
TermOne search request: a pattern plus whether it applies to filenames or file contents. A single pass can run many terms at once.
WildcardA filename pattern where an asterisk stands for any characters and a question mark for a single character, such as *.log or report_?.txt.