Getting GTK# Apps to Run on Windows

In which I explain why GTK# applications built in Monodevelop on Linux don’t run on Windows, and explain how to fix this…

As I’ve mentioned elsewhere, I’ve been working a lot recently with C# via Monodevelop to create applications that will work cross-platform (specifically Linux, Windows and Mac).

As you probably know, C# and the other .NET languages don’t compile down to machine code but to CIL (Common Intermediate Language) bytecode which is then interpreted by a JIT (just-in-time) compiler when the application runs. This means I can compile a “hello world” console application on Linux, take the resulting hello.exe and run it directly on Windows.

That’s great for command-line applications, but what if you want to do the same with a GUI application?

Firstly, Monodevelop does support WinForms – but it lacks any kind of GUI designer for this. The built-in designer (called Stetic) outputs GTK#, which is a better option for cross-platform apps anyway – it just takes a bit of re-adjustment if you’re used to building WinForms apps (for example the control property equivalent to “Enabled” is called “Sensitive” – not immediately apparent!).

So if I build an equivalent “hello world” GTK# application consisting of, say, one window with one button that just closes the app, that resulting guihello.exe (or whatever I call it) should run on Windows, right?

Um, no, firstly the obvious point – if you want to run GTK apps on Windows you need the GTK runtimes. Install those on Windows and you should be good to go, right? No, there’s one other gotcha. (Before that – a quick aside – if you’ve experimented with mkbundle to create static EXEs which package up all dependencies [to avoid needing runtimes], note that it doesn’t cover GTK# – you’ll still need to ensure that’s installed on the target machine).

So, what’s the second problem? OK, I try to run guihello.exe on Windows by double clicking on it. Hourglass for a few seconds, then nothing. Hmmm.

Looking in the Windows Event Viewer, I see the following error:

Application: guihello.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.IO.FileNotFoundException
at MainWindow.Build()
at MainWindow..ctor()
at guihello.MainClass.Main(System.String[])

That’s a System.IO.FileNotFoundException exception being thrown before we even get a chance to catch anything. It turns out the problem lies with a reference which is added automatically to Monodevelop’s GTK#-based projects:  Mono.Posix – which, if your target machine just has the normal Microsoft .NET runtimes installed, won’t exist.

So, remove that reference. After you do that you’ll find that there will be lines in the auto-generated Build() method for the form which now fail – for example:

this.Title = global::Mono.Unix.Catalog.GetString ("MainWindow");

The GetString() call is to allow for internationalisation / translations. For this test I just changed the lines to use hard-coded strings such as:

this.Title = "Hello World";

Rebuild, copy the file over to Windows, et voilà, it now runs.

If you want to prevent Monodevelop from keeping putting back a reference to Mono.Posix and making strings translatable, whenever you enter a string into a widget’s property in the designer, click the “…” button and uncheck “Translatable” in the resultant dialog. Of course this then gives you the problem that you’ve got hard-coded strings, but that’s something for another post some time.

2 Replies to “Getting GTK# Apps to Run on Windows”

  1. I have followed your post and for convenience, I have been testing on wine. I have previously tested a regular .NET Core program, to ensure that wine is not the problem. Using gtk, however, fails. For some reason, the error shows “gtk-sharp, Version=″ even though at no point did I use that version of gtk. My references are the following:





    The error is below.

    0009:fixme:ntdll:NtQuerySystemInformation info_class SYSTEM_PERFORMANCE_INFORMATION
    0009:fixme:ntdll:EtwEventRegister ({319dc449-ada5-50f7-428e-957db6791668}, 0x10023780, 0x10071b20, 0x10071b38) stub.
    0009:fixme:ntdll:EtwEventSetInformation (deadbeef, 2, 0x10003109, 28) stub
    0009:fixme:ntdll:EtwEventRegister ({319dc449-ada5-50f7-428e-957db6791668}, 0xa61d60, 0xf01048, 0xf01060) stub.
    0009:fixme:ntdll:EtwEventSetInformation (deadbeef, 2, 0x89060d, 28) stub
    0009:fixme:kernelbase:QuirkIsEnabled3 (0032F518, FFFFFFFF) stub!
    0009:fixme:heap:GetNumaHighestNodeNumber semi-stub: 0032FC4C
    0009:fixme:ntdll:EtwEventRegister ({e13c0d23-ccbc-4e12-931b-d9cc2eee27e4}, 0xb6b9f0, 0xf010b8, 0xf0cb50) stub.
    0009:fixme:ntdll:EtwEventRegister ({763fd754-7086-4dfe-95eb-c01a46faf4ca}, 0xb6b9f0, 0xf013c8, 0xf01540) stub.
    0009:fixme:ntdll:EtwEventRegister ({a669021c-c450-4609-a035-5af59af4df18}, 0xb6b9f0, 0xf0b840, 0xf0cb60) stub.
    0009:fixme:ntdll:EtwEventRegister ({cc2bcbba-16b6-4cf3-8990-d74c2e8af500}, 0xb6b9f0, 0xf01210, 0xf01288) stub.
    0009:fixme:wer:WerRegisterRuntimeExceptionModule (L”C:\\windows\\Microsoft.NET\\Framework\\v4.0.30319\\mscordacwks.dll”, 0x880000) stub!
    0009:fixme:path:parse_url failed to parse L”gtk-sharp”
    0009:fixme:nls:LCIDToLocaleName unsupported flags 8000000
    0009:fixme:nls:get_dummy_preferred_ui_language (0x8 0x32d454 (nil) 0x32d450) returning a dummy value (current locale)
    0009:fixme:nls:get_dummy_preferred_ui_language (0x8 0x32d454 0x867e78 0x32d450) returning a dummy value (current locale)
    0009:fixme:advapi:RegisterEventSourceW ((null),L”.NET Runtime”): stub
    0009:fixme:advapi:ReportEventW (0xcafe4242,0x0001,0x0000,0x00000402,(nil),0x0001,0x00000000,0x32d110,(nil)): stub
    0009:err:eventlog:ReportEventW L”Application: Cyclone.exe\nFramework Version: v4.0.30319\nDescription: The process was terminated due to an unhandled exception.\nException Info: System.IO.FileNotFoundException\n at Cyclone.MainClass.Main(System.String[])\n\n”
    0009:fixme:advapi:DeregisterEventSource (0xcafe4242) stub

    Unhandled Exception: 0009:fixme:ver:GetCurrentPackageId (0x32b830 (nil)): stub
    0009:fixme:ntdll:EtwEventRegister ({8e9f5090-2d75-4d03-8a81-e5afbf85daf1}, 0x37302be, (nil), 0x13a76f4) stub.
    System.IO.FileNotFoundException: Could not load file or assembly ‘gtk-sharp, Version=, Culture=neutral, PublicKeyToken=35e10195dab3c99f’ or one of its dependencies. Archivo no encontrado.
    at Cyclone.MainClass.Main(String[] args)
    wine: Unhandled exception 0xe0434352 in thread 9 at address 7B00DD59 (thread 0009), starting debugger…

    Although I don’t know if you’ll have the time to go through this, I would really appreciate your knowledge on the topic. Using C# hasn’t exactly been a good experience so far. I have spent more time trying to run the program than actually creating it. Thanks for your help.

Leave a Reply

Your email address will not be published. Required fields are marked *