I'm still hoping for a better answer from someone who knows a more idiomatic way to accomplish this, but in case there isn't one, for the benefit of future googlers, here's what I've done just to get it working for now:
From my Linux Mint installation, I copied /usr/lib/cli/binfmt-detector-cli
. This file is provided by the Ubuntu mono-runtime package. I don't like grabbing an executable from another distro, but it should be a fairly simple executable that doesn't rely on much that might differ between different distros, as long as they're the same platform.
Alternatively, the source code can be retrieved and built:
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
is a simple command that tests whether a file is a CLI executable, returning 0
or 1
on exit to indicate yes or no.
My Manjaro installation doesn't have a /usr/lib/cli
directory, so I copied this file straight to /usr/bin/
. Then a wrote a short shell script and saved it as /usr/bin/binfmt-mono-wine
:
#!/bin/bash
if /usr/bin/binfmt-detector-cli "$1"; then
mono "$@"
else
wine "$@"
fi
Then I edited /usr/lib/binfmt.d/mono.conf
, changing
:CLR:M::MZ::/usr/bin/mono:
to
:CLR:M::MZ::/usr/bin/binfmt-mono-wine:
and /usr/lib/binfmt.d/wine.conf
, changing
:DOSWin:M::MZ::/usr/bin/wine:
to
:DOSWin:M::MZ::/usr/bin/binfmt-mono-wine:
You can see that both formats are now handled by the shell script, which uses the detector borrowed from Ubuntu to determine which command to launch.
Next, I had to deregister the old handlers and register the new ones. I found out that systemd has a service that will do that:
sudo /usr/lib/systemd/systemd-binfmt mono.conf
sudo /usr/lib/systemd/systemd-binfmt wine.conf
The last thing to do is to register a pacman hook so that future upgrades to mono and wine don't overwrite my changes to their binfmt configurations. I created /etc/pacman.d/hooks/binfmt-mono-wine.hook
with these contents:
[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