#terminal #cli #console

app dcmd

Windows console & window management CLI: resize, position, always-on-top, hide/show, font, screen buffer control

2 releases

0.1.9 Jul 23, 2026
0.1.8 Jul 14, 2026

#82 in Windows APIs

MIT license

52KB
886 lines

dcmd

CI Release Crates.io License: MIT

A Windows console & window management CLI. dcmd is a from-scratch Rust port of a long-standing Python utility of the same name: it resizes and repositions the console window, pins arbitrary windows always-on-top, hides/shows/minimizes/maximizes/restores windows by name or PID, changes the console font, and inspects/resizes the console screen buffer — all through direct Win32 API calls (no shelling out to mode.com or PowerShell).

Platform: Windows only. dcmd talks directly to user32.dll/kernel32.dll via the windows crate. The crate still builds on other platforms (handy for docs.rs and Linux/macOS contributors), but every command exits with an error there.

Install

From crates.io

cargo install dcmd

From a release binary

Grab the latest .zip for your architecture from the Releases page and put dcmd.exe somewhere on your PATH.

From source

git clone https://github.com/cumulus13/dcmd-rs
cd dcmd-rs
cargo build --release
# binary at target/release/dcmd.exe

Usage

dcmd [OPTIONS]

Sizing / positioning
  -W, --width <PIXELS>            Set console window width
  -H, --height <PIXELS>           Set console window height
  -x, --xpos <N|left|right|center> X position
  -y, --ypos <N|top|bottom|center> Y position
  -c, --center                    Center the window (overrides -x/-y)
      --get-current-size, -gs     Print this console window's size/position
      --get-screensize, -gS       Print the primary screen resolution

Screen buffer
      --get-buffer, -gb           Print current console screen buffer info
      --buffer-row, -br <N>       Set screen buffer rows
      --buffer-column, -bc <N>    Set screen buffer columns

Font
  -f, --font <NAME>               Console font name        [default: Consolas]
      --font-size, -fs <N>        Console font size          [default: 13]
      --font-bold, -fb <N>        Console font weight         [default: 400]

Window listing
  -l, --list-window               List named/titled windows
      --list-all-window, -la      List every top-level window
      --list-window-hide, -lh     List currently hidden windows

Always-on-top
  -t, --always-top <NAME>         Pin a window (by title) always-on-top
      --not-always-top, -nt <NAME> Unpin a window from always-on-top
  -T, --always-top-this           Pin *this* console window always-on-top
      --not-always-top-this, -nT  Unpin *this* console window

Bulk window actions (accept one or more NAME/PID tokens)
      --hide, -hd [NAME|PID ...]  Hide matching window(s)
  -s, --show, -sw [NAME|PID|all ...] Show matching window(s) ("all" = every hidden one)
  -M, --maximize [NAME|PID ...]   Maximize matching window(s)
  -m, --minimize [NAME|PID ...]   Minimize matching window(s)
  -r, --restore [NAME|PID ...]    Restore & focus matching window(s)

Misc
  -F, --find <NAME|PID>           Find a process by name or PID
      --wait <SECONDS>            Sleep before executing
  -d, --debug                     Verbose logging
  -h, --help                      Print help
  -V, --version                   Print version

About the two/three-letter short flags (-gb, -bc, -br, -fs, -fb, -lh, -la, -nt, -nT, -gS, -gs, -hd, -sw): these mirror the original Python argparse tool's flag set, but clap (the CLI parser dcmd uses) only supports single-character short flags — it has no native concept of a multi-letter, single-dash flag. dcmd restores them via a small pre-parse rewrite step (src/shortflags.rs) that expands each alias to its --long form before clap ever sees argv, so dcmd -bc 200 and dcmd --buffer-column 200 are exactly equivalent. -gS and -gs are deliberately case-sensitive and distinct, same as the original.

Examples

# Move this console to the top-right corner, 900x500
dcmd -W 900 -H 500 -x right -y top

# Center this console window
dcmd -c

# Pin Notepad always-on-top
dcmd -t notepad

# Hide every window whose title contains "Slack"
dcmd --hide slack

# Show every hidden window
dcmd -s all

# List all visible, titled windows
dcmd -l

# Bump the console font
dcmd -f "Cascadia Mono" --font-size 16

# Resize the screen buffer to 200 columns x 3000 rows
dcmd --buffer-column 200 --buffer-row 3000

When a name/PID filter matches more than one window, dcmd prints a numbered list and prompts for a selection (or all for bulk actions), same as the original Python tool.

Design notes

  • Backend: windows crate — the official, metadata-generated Win32 bindings (no hand-rolled FFI, no winapi).
  • Process enumeration: sysinfo, used only for falling back to a process name when a window has no title and for --find.
  • CLI parsing: clap (derive API).
  • Errors: typed via thiserror, surfaced through anyhow at the top level.
  • Modules:
    • src/win/console.rs — screen buffer, console window rect, font (SetConsoleWindowInfo, SetConsoleScreenBufferSize, SetCurrentConsoleFontEx, GetConsoleScreenBufferInfo).
    • src/win/window.rs — window enumeration & manipulation (EnumWindows, MoveWindow, SetWindowPos, ShowWindow).
    • src/win/process.rs — process listing/filtering.
    • src/win/manager.rs — CLI-to-Win32 orchestration (selection prompts, filter resolution).
    • src/shortflags.rs — expands two/three-letter short aliases (-bc, -gs, ...) to their --long form before clap parses argv.

Development

cargo fmt
cargo clippy --all-targets --all-features -- -D warnings
cargo test
cargo build --release

CI runs fmt, clippy, and a build+test matrix (x86_64/i686 MSVC) on every push/PR via .github/workflows/ci.yml.

Releasing

Pushing a tag matching v*.*.* (e.g. v0.1.0) triggers .github/workflows/release.yml, which:

  1. Builds release binaries for x86_64, i686, and aarch64 Windows (MSVC).
  2. Zips each binary with README.md/LICENSE and attaches it to a GitHub Release (auto-generated notes).
  3. Publishes the crate to crates.io using the CARGO_REGISTRY_TOKEN repository secret.

Bump version in Cargo.toml to match the tag before tagging — the publish job fails fast if they disagree.

License

MIT © Hadi Cahyadi — see LICENSE.

👤 Author

Hadi Cahyadi

Buy Me a Coffee

Donate via Ko-fi

Support me on Patreon

Dependencies

~7–49MB
~740K SLoC