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
Stack:
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.

3 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=3.0.0.0″ even though at no point did I use that version of gtk. My references are the following:

    glib-sharp-2.0

    gtk-sharp-2.0

    gtk-sharp-2.0

    gtk-sharp-beans-2.0

    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:reg:GetEnabledXStateFeatures
    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:reg:GetEnabledXStateFeatures
    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=3.0.0.0, 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.

  2. As these appear to be Wine errors, your first test should be to run this under native Windows and see how it behaves. If you specifically want to investigate the errors you’re seeing, you should post the issues in https://forum.winehq.org/viewforum.php?f=2 – hope this helps a little, at least!

  3. I finally tested this on windows. I installed the GTK# runtime. Then ran the executable. As you describe, it appears to load, but ultimately doesn’t work. I did, however, delete the reference to Mono.Posix.

    The windows event viewer shows this error:

    Nombre de registro:Application
    Origen: .NET Runtime
    Fecha: 28/03/2020 06:14:01 p. m.
    Id. del evento:1026
    Categoría de la tarea:Ninguno
    Nivel: Error
    Palabras clave:Clásico
    Usuario: No disponible
    Equipo: DESKTOP-20AK4HL
    Descripción:
    Aplicación: Cyclone.exe
    Versión de Framework: v4.0.30319
    Description:The process was terminated due to an unhandled exception
    Exception Info: System.IO.FileNotFoundException
    at Cyclone.MainClass.Main(System.String[])

    XML de evento:

    1026
    2
    0
    0x80000000000000

    472
    Application
    DESKTOP-20AK4HL

    Aplicación: Cyclone.exe
    Versión de Framework: v4.0.30319
    Description:The process was terminated due to an unhandled exception
    Exception Info: System.IO.FileNotFoundException
    at Cyclone.MainClass.Main(System.String[])

    And also this error:

    Nombre de registro:Application
    Origen: Application Error
    Fecha: 28/03/2020 06:14:01 p. m.
    Id. del evento:1000
    Categoría de la tarea:(100)
    Nivel: Error
    Palabras clave:Clásico
    Usuario: No disponible
    Equipo: DESKTOP-20AK4HL
    Descripción:
    Nombre de la aplicación con errores: Cyclone.exe, versión: 1.0.7392.31917, marca de tiempo: 0x5e7f8cda
    Nombre del módulo con errores: KERNELBASE.dll, versión: 10.0.18362.719, marca de tiempo: 0x4061c730
    Código de excepción: 0xe0434352
    Desplazamiento de errores: 0x00114192
    Identificador del proceso con errores: 0x2174
    Hora de inicio de la aplicación con errores: 0x01d6055ef2d2cb2d
    Ruta de acceso de la aplicación con errores: C:\Users\*****\Downloads\Cyclone.exe
    Ruta de acceso del módulo con errores: C:\WINDOWS\System32\KERNELBASE.dll
    Identificador del informe: 5934e14b-478c-4531-8794-d2b796f43bf9
    Nombre completo del paquete con errores:
    Identificador de aplicación relativa del paquete con errores:
    XML de evento:

    1000
    2
    100
    0x80000000000000

    473
    Application
    DESKTOP-20AK4HL

    Cyclone.exe
    1.0.7392.31917
    5e7f8cda
    KERNELBASE.dll
    10.0.18362.719
    4061c730
    e0434352
    00114192
    2174
    01d6055ef2d2cb2d
    C:\Users\*****\Downloads\Cyclone.exe
    C:\WINDOWS\System32\KERNELBASE.dll
    5934e14b-478c-4531-8794-d2b796f43bf9

    My theory is that, somehow the program is asking for gtk-3, even though its references are all to gtk-2.12. The reason I say this is because this showed up when I tried running it with wine:

    “System.IO.FileNotFoundException: Could not load file or assembly ‘gtk-sharp, Version=3.0.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f’ or one of its dependencies. File not found.”

    I already posted the references in the other comment, if you want to take a look.
    As you can see, the windows error is not very helpful, due to the fact I don’t even know what file is the one missing. Also, forgive the fact that some of the error messages are in Spanish. I tried translating the important bits.

Comments are closed.