0

The answer superuser.com/a/1252579/143180 describes a WSL shell command that will open a file in Windows' default application.

cmd.exe /c start <file>

If a file name contains spaces then this command fails to open the file. It instead opens the Windows command line in a new window.

How do we amend this command to open a file in Windows' default application from a WSL shell? Is there a more effective command to use in this case?

I have tested variations of this command with quotes around the file name (both "" and ''), escaped spaces, escaped quotes, and similar variations on the command "%localappdata%/lxss/$(readlink -f $some_relative_path)" found in the comments to the answer above.

1

2 Answers 2

1

Unfortunately, there's no single answer that works 100% of the time for all environments, that I know of.

BEST - parse the full path with bash

I would recommend saving this as a shell script in a folder in your $PATH. This accepts full and relative paths, even of multiple files, then feeds it to the binary you want. In this case cmd.exe

#!/usr/bin/env bash
OIFS="$IFS"
IFS=$' \t\n'

if [[ "$@" =~ \/mnt\/([a-zA-Z]+)\/ ]]; then 
    cmd.exe /c start '' "${@/$BASH_REMATCH/${BASH_REMATCH[1]}\:\/}"
else
    cmd.exe /c start '' "$@"
fi

The section \/mnt of \/mnt\/([a-zA-Z]+)\/ in line 5 corresponds to your root. So if you have a different root, set the regular expression accordingly.

Option 2 - Create a function

As an alias, short but more unreliable.

alias cmd="cmd.exe /c start '' "${@//&/^&}""
Or

save it in one of your shell, eg: bash .bashrc .*rc files.

cmd() {
IFS=$' \t\n'
cmd.exe /c start '' "$@"
}

This works if you are invoking the file from the current shell. Thus it requires a relative path from your current directory and the escape of white spaces with a forward slash. if Your file is in the ./org folder.

eg: cmd org/Read\ me\ Official.html

To make it always relative to a particular folder, like $HOME you can append

cd $HOME && cmd.exe /c start '' "$@"

This option even accepts a program like notepad and the file with the whitespaces in the name.

eg: cmd onenote another\ file.txt

An alternative to cmd.exe /c start '' "$@" is rundll32.exe url,OpenURL '' "$@" which can have different parsing depending on your shell.

option 3 - bodge it

You can use xdg-open in combination with wsl-open a script that allows you to use Windows binaries as default and does some of the heavy weight lifting of parsing.

or use wslpath in a function to get the realpath.

cmd() {
  CMD=$1
  shift;
  ARGS=$@
  WIN_PWD=`wslpath -w "$(pwd)"`
  cmd.exe /c "pushd ${WIN_PWD} && ${CMD} ${ARGS}"
}

In any case it's a pain in the ass.

1

I found an answer to this question while drafting it. This command appears to work:

cmd.exe /c start "open file" "<file name>"

Attempted explanation

From the start helpfile:

Start a program, command or batch script (opens in a new window.) [Emphasis added.]

Syntax

START "title" [/D path] [options] "command" [parameters]

and

Always include a TITLE this [sic] can be a simple string like "My Script" or just a pair of empty quotes ""

According to the Microsoft documentation, the title is optional, but depending on the other options chosen you can have problems if it is omitted.

If the first argument we pass to start is a quoted string, then the command interprets this argument as a window TITLE. If the first argument is not quoted, then the command assumes we are skipping the TITLE argument. As a consequence, quoted filenames as the first and only argument will fail to open the file.

Adding any quoted TITLE argument appears to result in a working command.

1
  • I will accept a better answer to this question if anyone knowledgeable about the start command provides one. Sep 3, 2019 at 17:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .