-
Notifications
You must be signed in to change notification settings - Fork 850
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Launching Win32 applications from within WSL #1243
Comments
What if you invoke sublime_text.exe directly? I think the issue is that you are passing a Linux path to cmd.exe. We don't do any translation of command line arguments. |
Yes, I'm able to invoke the executable directly from the parent folder and it will launch properly. I'm able to work around this by adding the "C:\Program Files\Sublime Text 3" folder to my path and run sublime_text.exe directly. |
@jasonNXP Thanks for confirming. |
@benhillis I know this is a problem without a straightforward answer, but is it something you're looking into? It seems like the main problems would show up if you had a collision between a translated path and a Windows executable flag argument. One possibility is maybe to try to assume it's a path, see if it resolves to a file referenced through /mnt, and if it does, translate the path. Otherwise, pass it as an argument instead? It seems like the edge cases are probably few and far between. Another way might be to change the way the interpreter works, so that passing Windows executable flag arguments need to be specified by launching with a linux-style flag argument so that to launch
|
Does anyone know how Cygwin solves this problem? (Specifically, what rules they use for path translation.) As I recall, they attempt to do so, and their attempt works pretty well. |
@aseering I have cygwin installed, and I don't understand how it works actually... It seems highly inconsistent. I'm in my cygwin home, and here's how it goes:
This test quickly explodes and starts outputting what appear to be strange garbage characters after I tell it that test2 should be a directory, not so good. Then when I try to do it with The reason probably why you are thinking it works alright is that cygwin seems to alias |
"Magically" converting paths on the command line was considered but I was concerned with converting something that was not really a path because it looked like one. Relative paths don't need to be converted since NT handles / and \ interchangeably - so this only effects specifying an absolute path. I'll run this by the team next week and see what people think. |
@benhillis Yeah, I am aware that this particular magic is hard, given how notoriously "un-robust" bash is at handling of character escapes. |
Relative paths sometimes need to be converted because some programs do not just forward their args to NT as a file to open, but interpret them directly, in which case everybody uses its own rules. However, it might cause more damages than good, given every Win32 program can parse its own command line and add its own special parsing rules, sometimes completely crazy (cmd.exe, I'm looking at you :) I think absolute path starting with /mnt/ should be safe enough and helpful to convert. The next problem is Win32 command line parameter escaping. Here the fact that it is done by the called program potentially using custom methods hits again badly, because you basically wants to escape according to CommandLineToArgvW / crt rules (which are probably the most commonly used), except that it won't work well for cmd.exe (which is a non-negligeable use case) - and interestingly also for bash.exe :P ... No perfect solution for that either I guess. |
Question for Windows folks (my background is more in Linux) -- can "/mnt/c" ever be a valid Windows path prefix? If not, one solution in principle (admittedly with various potential downsides) would be to make the regular Windows APIs treat it as an alias for "C:". Then, at least programs that pass the path through without trying too hard to parse it will succeed. |
@aseering Windows has at least 3 absolute path conventions, and this should conflict with none of them, it seems. |
@aseering, @fpqc A simple string-based solution will only work in the base case where entire drives are mounted under /mnt/. In the future we may allow arbitrarily mounting NTFS folders or volumes or mounting to places other than /mnt/. In that case the driver will need to be consulted to return the correct Windows path. I have some ideas for an approach that world work long-term, but my main concern is still with false positives. The problem is that cases where Windows apps implement their own "strange" argument parsing. Let's say app Foo.exe has a command line argument "/mnt/c". The binfmt interpreter is going to assume that's a path and convert it to C:\ and pass that to Foo.exe which may not be a valid argument. Kind of a contrived example, but that's the type of thing we're concerned with. I suppose if we make it a configurable behavior that takes away some of the risk. |
Windows Insider Build 17046 contains new 'wslpath' functionality that supports path translations. See the release notes for more details. |
Description:
Unable to invoke application with spaces in directory name
Expected results:
Assume it should invoke the application properly.
Windows build number:
14951
Steps / All commands required to reproduce the error from a brand new installation:
cmd.exe /c /mnt/c/Program\ Files/Sublime\ Text\ 3/sublime_text.exe
The system cannot find the path specified.
Strace of the failing command
strace cmd.exe /c /mnt/c/Program\ Files/Sublime\ Text\ 3/sublime_text.exe
execve("/mnt/c/Windows/System32/cmd.exe", ["cmd.exe", "/c", "/mnt/c/Program Files/Sublime Tex"...], [/* 16 vars */]) = 0
brk(NULL) = 0x7fffd4434000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2918290000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=54002, ...}) = 0
mmap(NULL, 54002, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f2918282000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\t\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1864888, ...}) = 0
mmap(NULL, 3967488, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f2917c30000
mprotect(0x7f2917df0000, 2093056, PROT_NONE) = 0
mmap(0x7f2917fef000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1bf000) = 0x7f2917fef000
mmap(0x7f2917ff5000, 14848, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f2917ff5000
close(3) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2918280000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2918270000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2918260000
arch_prctl(ARCH_SET_FS, 0x7f2918270700) = 0
mprotect(0x7f2917fef000, 16384, PROT_READ) = 0
mprotect(0x7f2918609000, 4096, PROT_READ) = 0
mprotect(0x7f2918225000, 4096, PROT_READ) = 0
munmap(0x7f2918282000, 54002) = 0
getpid() = 77
getcwd("/home/public", 4096) = 13
open("/dev/lxssclient", O_RDWR) = 3
ioctl(3, _IOC(0, 0x00, 0x2f, 0x22), 0x7fffdcbe31b0) = 0
brk(NULL) = 0x7fffd4434000
brk(0x7fffd4455000) = 0x7fffd4455000
ioctl(3, _IOC(0, 0x00, 0x3f, 0x22), 0x7fffdcbe3038) = 0
ioctl(3, _IOC(0, 0x00, 0x3f, 0x22), 0x7fffdcbe3038) = -1 EINVAL (Invalid argument)
ioctl(4, _IOC(0, 0x00, 0x97, 0x22), 0x7fffdcbe30f8) = 0
ioctl(4, _IOC(0, 0x00, 0xb7, 0x22), 0x7fffdcbe30f0) = 0
ioctl(4, _IOC(0, 0x00, 0xb7, 0x22), 0x7fffdcbe30f0) = 0
ioctl(4, _IOC(0, 0x00, 0xb7, 0x22), 0x7fffdcbe30f0) = 0
write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 197) = 197
read(4, "3\0\0\0\0\0\0\0", 8) = 8
ioctl(4, _IOC(0, 0x00, 0x9b, 0x22), 0x7fffdcbe31a8) = 0
write(4, "3\0\0\0\0\0\0\0", 8) = 8
ioctl(5, _IOC(0, 0x00, 0xbf, 0x22)The system cannot find the path specified.
, 0x7fffdcbe3198) = 0
close(3) = 0
close(4) = 0
close(5) = 0
exit_group(1) = ?
+++ exited with 1 +++
Required packages and commands to install
Any Windows application with spaces in the directory name
The text was updated successfully, but these errors were encountered: