I've been having trouble with xah-open-in-external-app in Windows since the switch to using PowerShell's "Invoke-Item" cmdlet. But I think I've found a solution.
The problem is how cmd.exe and PowerShell handle file names and directories with spaces and other characters in them, and how cmdlets, their arguments, and strings are processed.
I've been having trouble with
xah-open-in-external-app
in Windows since the switch to using PowerShell's "Invoke-Item" cmdlet. But I think I've found a solution.The problem is how
cmd.exe
and PowerShell handle file names and directories with spaces and other characters in them, and how cmdlets, their arguments, and strings are processed.For example, say I have a file:
e:\Home\Archives\Test Directory\2020\Blah File [Old].txt
As currently written,
xah-open-in-external-app
will send this following tocmd.exe
:PowerShell -Command Invoke-Item E:\Home\Archives\Test Directory\2020\Blah File [Old].txt
Which barfs with this error:
Invoke-Item : A positional parameter cannot be found that accepts argument 'Directory\2020\Blah'
To get the command to work as intended, we need to do three things:
1) We need to use the
-LiteralPath
argument, which treats the string containing the path as literal, and containing no PowerShell wildcards2) We need to double-quote the cmdlet and its argument to separate it from the path to our file, and
3) We need to single-quote the fully-expanded path to our file, so PowerShell can handle the spaces.
The final command
cmd.exe
needs to open the example above is:PowerShell -Command "Invoke-Item -LiteralPath" 'E:\Home\Archives\Test Directory\2020\Blah File [Old].txt'
And to get that output, I modified the PowerShell call in
xah-open-in-external-app
to:(shell-command (concat "PowerShell -Command \"Invoke-Item -LiteralPath\" " "'" (shell-quote-argument (expand-file-name $fpath )) "'")))
Which works as intended for everything I've tested so far.
Also: buying your tutorial is how I learned Emacs. I really appreciate all the work you do!