Why is Ubuntu trying to open my Mono app with Wine instead of Mono?

5

2

So, I have compiled a C# program on Linux using MonoDevelop. When I try to execute the resulting binary, my system tries and fails to run it as a windows executable, with wine. Wine gives me the following message:

$ ~/bin/MyMonoApp
wine: Install the Windows version of Mono to run .NET executables
~/bin/MyMonoApp: command not found

I can only convince it to run by explicitly calling mono:

$ mono ~/bin/MyMonoApp

So, how can I make this the default, so I don't have to explicitly call mono every time?

Ryan C. Thompson

Posted 2010-08-24T15:52:57.593

Reputation: 10 085

Type: file MyMonoApp and tell us the results. – kmarsh – 2010-08-24T18:56:51.300

My laptop's cooling fan just died, so I can't work on fixing this until the new one arrives. – Ryan C. Thompson – 2010-08-25T02:09:05.827

MyMonoApp: PE32 executable for MS Windows (console) Intel 80386 32-bit Mono/.Net assembly – Ryan C. Thompson – 2010-08-29T20:58:04.423

Answers

7

Execution of binaries in the Linux kernel is controlled via the binfmt_misc module (short for “miscellaneous binary formats”). The way it works is that the kernel looks at the first few bytes of the file and sees if there is a “magic number” that characterizes a known file format. The idea is that if the kernel sees the magic number of a .NET executable, it calls mono; if it sees the magic number of a jar (Java virtual machine binary), it calls a JRE; etc.

The problem with Mono and Wine is that the magic number is the same — a .NET executable is a Windows executable. If both formats are registered with binfmt_misc, whichever is registered last wins. Oops.

On a Debian-derived system, the magic number for Windows executables doesn't invoke wine or mono directly: it goes via a script that performs additional tests to decide which environment to use. The script in question was initially written for Debian; it could be used by other distributions (for instance Ubuntu has kept it).

Apparently your distribution (which one? you don't say!) doesn't use it. The first thing to check would be if some updates you haven't applied includes something similar. If you'd like to port the mechanism, here's where to find the bits; it's a small programming task. The script is /usr/share/binfmt-support/run-detectors in the binfmt-support package (you need the libraries in /usr/share/perl5/Binfmt as well); for mono, the detector is /usr/lib/cli/binfmt-detector-cli in the mono-common or mono-runtime package.

If your distribution has no special support, and you don't care about wine binaries, a more manual route would be easier. The binfmt_misc module is controlled via the /proc/sys/fs/binfmt_misc directory. You can register a format by writing to /proc/sys/fs/binfmt_misc/register; each file in this directory other than register and status represents a registered format. Be careful when writing to register: if you accidentally register a magic number that matches Linux native executables (ELF), you're likely to hose your system with no remedy other than rebooting. To unregister the wine format, echo -1 to /proc/sys/fs/binfmt_misc/wine. The binfmt_misc module is documented in Documentation/binfmt_misc.txt.gz in the Linux kernel documentation.

One solution to your problem would be to unregister the wine format; you'd have to do that after whichever boot script registers binary formats. An alternative solution is to figure out where in the boot process the wine format is registered and skip this part. A third solution is to find a way to distinguish .NET executables from other Windows executable and register the .NET magic number after the generic Windows magic number.

Gilles 'SO- stop being evil'

Posted 2010-08-24T15:52:57.593

Reputation: 58 319

I'm using Ubuntu Lucid. I guess the debian script hasn't made it in yet. Could I just download the debian binfmt-support package and build it on ubuntu? – Ryan C. Thompson – 2010-08-29T20:56:43.253

@Ryan: Ubuntu lucid includes the same support, so something else is wrong. Do /proc/sys/fs/binfmt_misc/cli and /proc/sys/fs/binfmt_misc/wine both show interpreter /usr/share/binfmt-support/run-detectors? If you run /usr/lib/cli/binfmt-detector-cli ~/bin/MyMonoApp; echo $?, does it show 0 or 1 (0 means that your executable has been identified as mono)? – Gilles 'SO- stop being evil' – 2010-08-29T21:46:07.357

It shows zero. But it still wants to run it with wine. – Ryan C. Thompson – 2010-09-18T01:35:32.813

Hmm. There is no /proc/sys/fs/binfmt_misc/cli. and /proc/sys/fs/binfmt_misc/cli shows interpreter /usr/bin/wine. – Ryan C. Thompson – 2010-09-18T01:37:44.150

@Ryan: /proc/sys/fs/binfmt_misc/cli should exist if /usr/bin/mono does, they're provided by the same package. Does /var/lib/binfmts/cli exist? Is the mono command /usr/bin/mono from the mono-runtime package? On the wine side, did you mean …/wine shows interpreter /usr/bin/wine? Is that wine from Ubuntu universe or from another source? – Gilles 'SO- stop being evil' – 2010-09-18T11:34:40.243

There is no /var/lib/binfmts/cli, but there is /usr/share/binfmts/cli. – Ryan C. Thompson – 2010-09-28T22:58:53.063

Strange. Look if cli has been disabled somehow (but I think that would only happen if you do it explicitly) by running /usr/sbin/update-binfmts --display. If it is, you can reenable it with sudo update-binfmts --enable cli. – Gilles 'SO- stop being evil' – 2010-09-28T23:23:11.063