0

In my Linux Mint installation, I can directly execute a PE executable at the command line, and if it's a .NET/CLI executable, then it will automatically execute it with Mono, and otherwise, it will automatically execute it with Wine.

This works because binfmt is configured to run /usr/lib/binfmt-support/run-detectors for both CLI and Wine executables. This runs a series of detectors configured in /var/lib/binfmts to determine what type of PE executable it is and execute the appropriate command to run it.

In Manjaro, I have binfmt, but I don't have run-detectors. So I guess the first match in /proc/sys/fs/binfmt_misc wins, and I guess since I installed Wine before I installed Mono, that's the one that wins. That my supposition, anyway. The symptom is that whenever I execute an .exe file from the command line, it runs Wine, even if it's a .NET executable.

I can't find a package that seems to supply this run-detectors utility. Is there something like it in the standard or community repositories, or is there some other common way to set this up in the Arch world?

0

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.

This 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.