Skip to content

Instantly share code, notes, and snippets.

@donnaken15
Created February 23, 2025 11:32
Show Gist options
  • Select an option

  • Save donnaken15/b95df36d75c044b7a039cc39869d65a5 to your computer and use it in GitHub Desktop.

Select an option

Save donnaken15/b95df36d75c044b7a039cc39869d65a5 to your computer and use it in GitHub Desktop.
run windows programs from WSL with path conversion and support running functions straight from cmd
#!/bin/zsh
# execute Windows program from WSL shell
# where Windows paths are present, and
# converted to normal paths like for compact
#
# rename this script to anything besides wsl2exe
# to act as a proxy to the program you want to execute,
# as long as it refers to a program existing in PATH,
# and that windows PATH is added to the WSL instance
[ ! -f '/proc/sys/fs/binfmt_misc/WSLInterop' ] && {
orig="$(which -a "${0:t}" | sed -n 2p)"
[ -s "$orig" ] && exec -- "$orig" ${@} || {
echo "Original command not found: ${0:t}"
}
exit
}
# don't append .exe to the command argument
COMMAND=""
[ "${0[-7,-1]:l}" = "wsl2exe" ] && {
[ $# -eq 0 ] && { echo "Usage: wsl2exe [windows command] [args...]"; exit; }
COMMAND="$1"
shift
} || {
ALLOW_BUILTINS=0 # ???? *
COMMAND="$(basename "$0")"
}
declare -a ARGBUILDER
ARGBUILDER=()
# i just remembered, this will come from shell, not batch, dummy *
[ ${ALLOW_BUILTINS:-1} -eq 1 ] && {
# (1) check for typed built in, to then turn into cmd /c
# reserved names come first, i.e. to run dir.exe from
# cygwin in the command line, it must be typed as "dir.exe"
# otherwise windows built in is ran
CMD_LOWER=${COMMAND:l}
()(( $@[(Ie)$CMD_LOWER] )) \
assoc cls copy date del dir dpath \
echo ftype forfiles mklink pushd \
popd set setlocal shift rem rmdir \
start time title type ver vol && {
got_builtin=1
use_cmd=1
}
}
[ ${got_builtin:-0} -eq 0 ] && {
# if above isn't the case
# (2) check paths for executables with following extensions
j=0
for i (com exe bat cmd) {
exe="${COMMAND}.${i}"
{ command -v "${exe}" &> /dev/null } && {
COMMAND="${exe}"
break
}
}
}
which wslpath >/dev/null 2>/dev/null && pathconv=wslpath || pathconv=cygpath
mountpoint=/mnt/
fix() {
a="$1"
# convert absolute linux paths to windows paths
case "$a" in
# uhhh https://learn.microsoft.com/en-us/windows/wsl/wsl-config#automount-settings
/tmp/*)
a="$($pathconv -a -w "${a:a:h}")\\${a:t}$([ -d "$a" ] && <<< \\)"
;;
$mountpoint*)
#[ -e "$a" ] && {
# TODO?: recursive check existence of upper and upper path
[ -d "${a:a:h}" ] && {
a="$($pathconv -a -m "${a:a:h}")${a:t}$([ -d "$a" ] && echo /)"
[ ${NBS:-0} -eq 1 ] && a=$(sed 's/\//\\\\\\\\/g' - <<< "${a}") # brain damage
}
#}
;;
# point to rootfs for folders in wsl???
/dev/null)
# ignore for cygwin programs??
a="NUL"
;;
esac
<<< "${a}"
}
ext="${COMMAND##*.}"
[ ${ext} = bat -o ${ext} = cmd ] && use_cmd=1
[ ${use_cmd:-0} -eq 1 ] && {
NBS=1 # NEED BACKSLASHES
ARGBUILDER+=("/c" "$(fix "$CMD_LOWER")")
COMMAND="cmd.exe"
}
# detect if running on WSL because I just
# hardlinked "compact" to here and wanted to
# use the script on Cygwin
# oops
# now want to use mp3_speedrun with this because bundows memory leak >:(
[ $# -gt 0 ] && for a in "$@"; do
[ "{{$a}}" = "{{-}}" ] &&
ARGBUILDER+=("-") || # so stupid
ARGBUILDER+=("$(fix "$a")")
done
$COMMAND "${ARGBUILDER[@]}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment