在我的Linux Mint安装中,我可以直接在命令行执行PE可执行文件,如果它是.NET/CLI可执行文件,那么它将自动使用Mono执行它,否则它将自动使用Wine执行它。
这有效是因为binfmt
配置/usr/lib/binfmt-support/run-detectors
为针对 CLI 和 Wine 可执行文件运行。这会运行一系列配置的检测器来/var/lib/binfmts
确定它是什么类型的 PE 可执行文件并执行适当的命令来运行它。
在Manjaro,我有binfmt
,但我没有run-detectors
。所以我猜第一场比赛/proc/sys/fs/binfmt_misc
获胜,而且我猜因为我在安装 Mono 之前安装了 Wine,所以那场比赛获胜。无论如何,这是我的假设。症状是,每当我.exe
从命令行执行文件时,它都会运行 Wine,即使它是 .NET 可执行文件。
我找不到似乎提供此run-detectors
实用程序的软件包。标准或社区存储库中是否有类似的东西,或者在 Arch 世界中是否有其他常见的方法来设置它?
答案1
我仍然希望从知道一种更惯用的方法来完成此任务的人那里得到更好的答案,但如果没有,为了未来的谷歌人的利益,这就是我现在所做的只是为了让它工作:
从我的 Linux Mint 安装中,我复制了/usr/lib/cli/binfmt-detector-cli
.该文件由Ubuntu提供单运行时包裹。我不喜欢从另一个发行版获取可执行文件,但它应该是一个相当简单的可执行文件,不依赖于不同发行版之间可能存在的差异,只要它们是相同的平台即可。
或者,可以检索并构建源代码:
git clone --filter=blob:none --depth 1 --no-checkout git://git.launchpad.net/ubuntu/+source/mono ubuntu-mono-binfmtdetect
cd ubuntu-mono-binfmtdetect
git sparse-checkout set debian/detector
git checkout
cd debian/detector
make
echo sudo install -o root -g root -m 0755 ./binfmt-detector-cli /usr/local/bin/
binfmt-detector-cli
是一个简单的命令,用于测试文件是否为 CLI 可执行文件,在退出时返回0
或1
来指示是或否。
我的 Manjaro 安装没有/usr/lib/cli
目录,因此我将此文件直接复制到/usr/bin/
.然后编写了一个简短的 shell 脚本并将其另存为/usr/bin/binfmt-mono-wine
:
#!/bin/bash
if /usr/bin/binfmt-detector-cli "$1"; then
mono "$@"
else
wine "$@"
fi
然后我编辑/usr/lib/binfmt.d/mono.conf
,改变
:CLR:M::MZ::/usr/bin/mono:
到
:CLR:M::MZ::/usr/bin/binfmt-mono-wine:
和/usr/lib/binfmt.d/wine.conf
, 改变
:DOSWin:M::MZ::/usr/bin/wine:
到
:DOSWin:M::MZ::/usr/bin/binfmt-mono-wine:
您可以看到这两种格式现在都由 shell 脚本处理,该脚本使用从 Ubuntu 借用的检测器来确定要启动哪个命令。
接下来,我必须取消注册旧的处理程序并注册新的处理程序。我发现 systemd 有一个服务可以做到这一点:
sudo /usr/lib/systemd/systemd-binfmt mono.conf
sudo /usr/lib/systemd/systemd-binfmt wine.conf
最后要做的事情是注册 pacman 钩子,以便将来对 mono 和 wine 的升级不会覆盖我对其 binfmt 配置的更改。我/etc/pacman.d/hooks/binfmt-mono-wine.hook
用这些内容创建了:
[Trigger]
Operation = Install
Operation = Upgrade
Type = File
Target = usr/lib/binfmt.d/mono.conf
Target = usr/lib/binfmt.d/wine.conf
[Action]
When = PostTransaction
Description = Updating binfmt configuration to use binfmt-mono-wine to differentiate between mono and wine executables
Exec = /usr/bin/xargs -I{} /usr/bin/sed -Ei 's_:/usr/bin/(mono|wine):_:/usr/bin/binfmt-mono-wine:_' /{}
NeedsTargets