如何从 WSL (Ubuntu) Bash 运行 Windows 可执行文件
Posted
技术标签:
【中文标题】如何从 WSL (Ubuntu) Bash 运行 Windows 可执行文件【英文标题】:How can I run a Windows executable from WSL (Ubuntu) Bash 【发布时间】:2016-12-19 15:07:09 【问题描述】:随着 2016 年夏季的 Windows 10 周年更新,可以在“轻量级”虚拟化子系统 Windows Subsystem for Linux (WSL) 中运行 ubuntu 二进制文件。 p>
不幸的是,启动 C:\Windows\System32\bash.exe
,另一个 bash
ELF 二进制文件会在 WSL 中启动一个进程,您无法从中逃脱!您只能启动其他 ELF 二进制文件。
那么如何从 Windows Bash 执行 *.exe
文件?[1]
[1] 在Microsoft's "official" GH support repo 中也提出了问题。
【问题讨论】:
另请参阅 Bash on Windows - alias for exe files 以了解避免在 shell 脚本中添加显式.exe
扩展的要求。
【参考方案1】:
本机解决方案
Windows 10 Insider Preview Update (14951) 提供的官方解决方案基于几乎被遗忘的binfmt_msc Linux 工具,用于启动二进制文件。 binfmt_misc 的注册命令如下所示(其中/init
是 win 可执行文件的临时 binfmt_misc“解释器”):
sudo echo ":WSLInterop:M::MZ::/init:" > /proc/sys/fs/binfmt_misc/register
然后 win-executable 将像常规程序一样启动:
$ export PATH=$PATH:/mnt/c/Windows/System32
$ notepad.exe
$ ipconfig.exe | grep IPv4 | cut -d: -f2
$ ls -la | findstr.exe foo.txt
$ cmd.exe /c dir
并不是说任何 win 可执行文件都必须驻留在 windows (DrvFs) 文件系统中 - 而不是在 Linux 的文件系统 (VolFs) 中 - 以便继承一个合适的 Windows 工作目录。
cbwin 替代方案
在您获得最新版本之前,cbwin 项目提供了一种解决方法,方法是在 WSL 中安装 3 个新的 linux 命令:
wcmd
:通过cmd.exe
调用win 可执行文件。
wrun
:与CreateProcess
同步调用一个win可执行文件,等待死亡(不使用cmd.exe
)。
wstart
:启动分离(异步)命令(使用cmd.exe
)。
要使用它们,您必须:
-
安装cbwin:
一个新的
outbash.exe
将安装在您的常规 Windows 文件系统中(在您的 %PATH%
中的某个位置),另外
WSL 文件系统中的 3 个 linux 命令。
使用outbash.exe
(无论您安装在哪里)来启动 WSL,而不是 C:\Windows\System32\bash.exe
!
使用这些命令之一为任何 win 可执行文件添加前缀,例如wrun notepad
.
提示:如果使用wcmd
或wrun
启动的可执行文件生成了任何子代,则这些子代仅在该可执行文件仍然存在时才能存活。
换句话说,尝试用wcmd
启动notepad.exe
是行不通的,因为记事本 将在启动后立即被杀死 -- 使用wrun
(同步)或@在这种情况下为 987654344@(异步)。
【讨论】:
哎哟!这是一种解决方法,但有时这就是我们所拥有的(赞成!)。感谢分享。 使用 Creators Update (15063),运行命令行和 GUI exe 都可以正常运行。 我必须使用echo ":WSLInterop:M::MZ::/init:" |sudo tee /proc/sys/fs/binfmt_misc/register
,否则它会说Permission denied
。【参考方案2】:
在 Windows 10 Creators Update(内部版本 1703,2017 年 4 月)中,这是本机支持的。因此,您现在可以从 Linux 运行 Windows 二进制文件...
notepad.exe
或任何其他.exe
(需要扩展名和needs being on your path,一些旧版本需要整个路径)
...反之亦然,使用以下方法之一:
bash.exe -c command_to_run
即:bash.exe -c ls
bash -c command_to_run
即:bash -c ls
wsl command_to_run
即:wsl "ls"
;或指定要用于运行它的发行版:
ubuntu run ls
有关详细信息,请参阅上面的链接文章。
【讨论】:
可能值得指出的是,他们将命令从bash
更改为 wsl
,但看起来 bash
仍然有效,但可能已被弃用。
请注意:您必须在 exe 中包含扩展名和大小写正确的名称才能正常工作。
我无法让它正常工作。例如,我安装了 firefox (firefox.exe
),但在 bash 提示符下键入 firefox.exe 会导致 firefox.exe: command not found
哦我明白了:需要运行/mnt/c/Program Files/Mozilla\ Firefox/firefox.exe
@xotonic 从 WSL bash 调用 windows exe - 您需要包含扩展名,即 nodepad.exe
【参考方案3】:
从命令行运行.exe
时,当通过exec()
从php 运行时,我无法让它工作。但是,添加 /init
确实有效。这是我在 Windows 上安装的 GraphicsMagick 的工作 /usr/local/bin/convert
文件:
#!/bin/sh
/init "$(ls /mnt/c/Program*/GraphicsMagick*/gm.exe|tail -1)" convert "$@"
【讨论】:
【参考方案4】:我对此有点困惑。我添加了一个符号链接:
$ ls -l /c
lrwxrwxrwx 1 root root 5 Dec 3 10:24 /c -> mnt/c
现在 ls /c 给出与 ls /mnt/c 相同的结果
但是现在: /c/Program\ Files/Java/jdk1.8.0_211/bin/java.exe -version ==> 什么都没有
但是:
/mnt/c/Program\ Files/Java/jdk1.8.0_211/bin/java.exe -version
java version "1.8.0_211" Java(TM) SE Runtime Environment (build 1.8.0_211-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode)
其他 Windows 可执行文件也会发生同样的情况。 WSL 是否有实现符号链接的错误?
【讨论】:
我也试过这个 - 直接创建了一个指向 .exe 的符号链接,仍然没有运气。 针对特定 .exe 的另一种解决方法(有点烦人)创建一个代理 bash 脚本 -/mnt/d/path/to/executable.exe "$@"
这对我来说已经足够了,我只是想访问 anaconda 的 Windows 安装。
截至今天,2020 年 11 月 9 日,/c/Program\ Files/Java/jdk1.8.0_211/bin/java.exe -version
为我提供了具有 /mnt
的确切输出。【参考方案5】:
为什么不直接使用
$ powershell.exe Start filename
Start
相当于 Windows 上的大多数 linux 上的 xdg-open
或 macOS 上的 open
,这意味着“使用默认桌面应用程序打开”。我喜欢给它起别名来打开。
【讨论】:
注意cmd.exe /c start
是一样的。以上是关于如何从 WSL (Ubuntu) Bash 运行 Windows 可执行文件的主要内容,如果未能解决你的问题,请参考以下文章