2 releases
Uses new Rust 2024
| new 0.1.2 | Dec 19, 2025 |
|---|---|
| 0.1.1 | Dec 19, 2025 |
#37 in Configuration
51KB
949 lines
Winbang
Winbang adds Unix-like shebang support to Windows, Allowing scripts to run without specifying an interpreter or requiring file extensions. It selects the interpreter from the shebang and can also use file-extension associations when present.
Installation
Cargo
cargo install winbang
Setup
To get the full benefits of Winbang the following is required:
- Manually associate desired filetypes to
winbang.exe(ideally.sh,.zsh,.py, and other common script extensions.) - Follow the instructions for [Extensionless File Association](### Extensionless File Association)
- Setup a [config file](## Config File Template) (optional, recommended)
Extensionless File Association
This unlocks the true potential of Winbang. Allowing for a Unix-like file experience making file extensions much less important and taking advantage of standard shebang lines and shebang-like lines.
-
Run in an elevated command prompt:
NOTICE
winbang.exepath may need adjustment based on your installation.
assoc .="No Extension"
ftype "No Extension"=^"^%USERPROFILE%\.cargo\bin\winbang.exe^" "%1"
assoc "No Extension"\DefaultIcon=%SystemRoot%\System32\imageres.dll,-68
DefaultIcon imageres.dll indexes:
15application icon68script icon102file icon
- Restart computer.
Behavior
When invoked from a command prompt, Winbang always executes the script. When invoked from a GUI context such as explorer.exe, it prompts the user for an action by default.
Winbang is extensible and supports file association by extension or shebang. Shebang runtimes can be proxied, for example mapping #!/bin/bash to C:\msys64\msys2_shell.cmd with appropriate arguments.
If no matching association exists in the configuration, Winbang searches for the interpreter in PATH.
env shebangs are supported via basic emulation rather than invoking the env binary. For example, #!/usr/bin/env python3 directly executes python3. The -S flag is supported, allowing multiple interpreter arguments (e.g. #!/usr/bin/env -S python3 -u -O). No other env flags are supported.
WARNING
By default an action prompt is shown when launched from a GUI shell, disabling this behavior could lead to an increased security risk. (The same risk as running any untrusted application/script.)
Config File Template
%PROGRAMDATA%/Winbang/config.toml or %APPDATA%/Winbang/config.toml
The configuration files will not merge, only one will be used. If
allow_user_config is set to true in the %PROGRAMDATA% config, then the user
config will be used. If not, the %PROGRAMDATA% config will be used.
config.toml
# allow_user_config = true # Optional, default is false, only valid in %PROGRAMDATA% config.
# List of GUI shells to use when launching files in GUI mode
gui_shells = ["explorer.exe", "dopus.exe"]
# Default operation if no file association matches
default_operation = "prompt" # Optional, default: "prompt", only affects when launched via GUI.
[default]
# Viewer used for regular files
view_runtime = "code"
#args = "$script"
[default_large]
# Viewer used for large files (>= 5MB)
size_mb_threshold = 5
view_runtime = "notepad++"
#args = "$script"
# [[file_associations]]
# exec_runtime = "deno" # Required
# view_runtime = "code" # Optional
# shebang_interpreter = "deno" # Optional
# extension = ".ts" # Optional
# exec_argv_override = "run @{script}" # Optional
# File associations
[[file_associations]]
exec_runtime = "python"
view_runtime = "thonny"
shebang_interpreter = "python"
extension = "py"
[[file_associations]]
exec_runtime = "ruby"
view_runtime = "code"
shebang_interpreter = "ruby"
extension = "rb"
default_operation = "prompt"
[[file_associations]]
exec_runtime = "C:\\msys64\\msys2_shell.cmd"
view_runtime = "code"
shebang_interpreter = "bash"
extension = "sh"
exec_argv_override = "-defterm -here -no-start -ucrt64 -shell bash -c \"$(cygpath -u @{script_unix})\""
[[file_associations]]
exec_runtime = "zsh"
shebang_interpreter = "zsh"
extension = "sh"
default_operation = "execute"
[[file_associations]]
exec_runtime = "deno"
extension = "ts"
shebang_interpreter = "deno"
exec_argv_override = "run -A @{script}"
[[file_associations]]
exec_runtime = "node"
shebang_interpreter = "node"
extension = "js"
[[file_associations]]
exec_runtime = "perl"
view_runtime = "runemacs"
shebang_interpreter = "perl"
extension = "pl"
exec_argv_override will expand the following special variables:
@{script}: The full script file path with double-backslashes (e.g.,C:\\Users\\username\\test.sh).@{script_unix}: The script file path with forward slashes (e.g.,C:/Users/username/test.sh).@{passed_args}: Additional arguments passed from the runtime to the script interpreter.
Example/Test Files
Deno Script
./denotest
#!/usr/bin/env deno
async function main() {
console.log("Hello from Deno!");
const fileName = "test.txt";
try {
await Deno.writeTextFile(fileName, "Hello from Deno!");
console.log(`File ${fileName} created successfully.`);
} catch (error) {
console.error(`Failed to create file ${fileName}:`, error);
}
const promptExit = prompt("Press Enter to exit...");
}
main();
Ruby Script
./rubytest
#!/usr/bin/env ruby
puts "Hello from Ruby!"
File.open("test.txt", "w") do |file|
file.write("Hello from Ruby!")
end
puts "Press Enter to exit..."
STDIN.gets
Dependencies
~116MB
~2M SLoC