OS docs: The method to restore windows 10 back to EARS Tablet 1 month ago
dll inital commit: necessary files to create linux software for ears 1 month ago
program bug: there is flcikering when we shift from one window to another 1 month ago
Readme.md docs: added os definition 1 month ago
ReadmeQuick.md inital commit: necessary files to create linux software for ears 1 month ago
Readme.md

Mono + GTK# + Glade — WSL Setup Guide

Table of Contents


Mono

1. Prerequisites

  • Windows 11 (or updated Windows 10) with WSL2 and WSLg enabled for GUI support
  • Ubuntu 24.04 (noble) or similar WSL distro

Check WSLg is active:

echo $DISPLAY

Should return something like :0. If empty, GUI apps won't display.


2. Install Mono

sudo apt update
sudo apt install mono-complete

Verify:

mono --version
mcs --version

3. Install GTK# (GTK# 3.0, for Ubuntu 24.04)

Note: gtk-sharp2 is not available on Ubuntu 24.04 (noble). Use gtk-sharp3 instead.

sudo add-apt-repository universe
sudo apt update
sudo apt install gtk-sharp3

Verify the package is registered:

pkg-config --list-all | grep gtk-sharp

Expected output: gtk-sharp-3.0 Gtk - Gtk

4. Install Glade (visual UI designer)

sudo apt install glade

Launch it:

glade

Design your UI visually, then save as yourfile.glade (XML format).


5. Optional: libgdiplus (only if using System.Drawing)

Only needed if your code uses System.Drawing.Bitmap, Graphics, etc. (not required for plain GTK#/Glade apps):

sudo apt install libgdiplus

6. Compiling & Running

Plain console C# program

mcs myprogram.cs
mono myprogram.exe

GTK# 3.0 program (no Glade)

mcs -pkg:gtk-sharp-3.0 myapp.cs
mono myapp.exe

GTK# 3.0 program using a Glade file

mcs -pkg:gtk-sharp-3.0 -pkg:glade-sharp-3.0 myapp.cs
mono myapp.exe

Make sure the .glade file referenced in code sits in the same folder (or update the path in new Builder("...")).


7. Minimal Working Examples

Hello World (console)

using System;

class Hello {
    static void Main() {
        Console.WriteLine("Hello from Mono in WSL!");
    }
}
mcs hello.cs
mono hello.exe

Hello World (GTK# window, no Glade)

using System;
using Gtk;

class GtkCheck {
    static void Main() {
        Application.Init();
        var win = new Window("Hello GTK#3");
        win.SetDefaultSize(300, 200);
        win.DeleteEvent += (o, args) => Application.Quit();

        var button = new Button("Click me");
        button.Clicked += (o, args) => Console.WriteLine("Clicked!");
        win.Add(button);

        win.ShowAll();
        Application.Run();
    }
}
mcs -pkg:gtk-sharp-3.0 gtkcheck.cs
mono gtkcheck.exe

Loading a UI built in Glade

using System;
using Gtk;

class Program {
    static void Main() {
        Application.Init();
        var builder = new Builder("myui.glade");
        builder.Autoconnect(new Program());

        var win = (Window)builder.GetObject("window1");
        win.DeleteEvent += (o, args) => Application.Quit();
        win.ShowAll();

        Application.Run();
    }
}
mcs -pkg:gtk-sharp-3.0 -pkg:glade-sharp-3.0 program.cs
mono program.exe

8. Custom Output Names, Targets & Exporting DLLs

By default, mcs file.cs names the output after the source file (file.exe). You can control this with -out: and change what kind of binary is produced with -target:.

8.1 Custom output name

mcs -pkg:gtk-sharp-3.0 Program.cs -out:MyCustomApp.exe

Run it the same way:

mono MyCustomApp.exe

8.2 -target options

TargetProducesNotes
exe (default)Console executableShows a console window when run on Windows
winexeWindows GUI executableNo console window — correct choice for GTK#/Glade GUI apps distributed on Windows
library.dll class libraryNo Main entry point required to run directly; used by other programs
module.netmoduleRarely used; for combining into a single assembly later

Your example, building a windowed GUI executable with a custom name:

mcs -target:winexe -pkg:gtk-sharp-3.0 Program.cs -out:programwin.exe

This produces programwin.exe, which on Windows will run without popping up a console window alongside your GTK window.

8.3 Exporting a DLL

If you want to package reusable code (helper classes, business logic, etc.) as a library instead of a standalone app:

mcs -target:library Program.cs -out:MyLibrary.dll
  • No Main() method is required in a library target (though it's fine if one class in your project has one — it just won't be used as an entry point for the DLL itself).
  • This creates MyLibrary.dll, a Mono/.NET assembly that other C# programs can reference.

8.4 Using a DLL in another program

Suppose MyLibrary.dll contains:

// MyLibrary.cs
namespace MyLib {
    public class Greeter {
        public string Greet(string name) => $"Hello, {name}!";
    }
}

Compiled with:

mcs -target:library MyLibrary.cs -out:MyLibrary.dll

Then in a separate consumer program:

// ConsumerApp.cs
using System;
using MyLib;

class ConsumerApp {
    static void Main() {
        var greeter = new Greeter();
        Console.WriteLine(greeter.Greet("World"));
    }
}

Compile it while referencing the DLL with -r::

mcs ConsumerApp.cs -r:MyLibrary.dll -out:ConsumerApp.exe

Run it (make sure MyLibrary.dll is in the same folder as ConsumerApp.exe, or on Mono's library search path):

mono ConsumerApp.exe

8.5 Combining -target:library with GTK# packages

If your DLL itself uses GTK# types (e.g., a shared custom widget), include the package flag when building the library too:

mcs -target:library -pkg:gtk-sharp-3.0 MyGtkWidgets.cs -out:MyGtkWidgets.dll

And reference both the package and the DLL when compiling the consumer:

mcs -pkg:gtk-sharp-3.0 ConsumerApp.cs -r:MyGtkWidgets.dll -out:ConsumerApp.exe

8.6 Quick reference

# Console exe, custom name
mcs Program.cs -out:myapp.exe

# Windowed (no console) exe, custom name
mcs -target:winexe -pkg:gtk-sharp-3.0 Program.cs -out:programwin.exe

# Class library (DLL)
mcs -target:library Library.cs -out:MyLibrary.dll

# Program referencing that DLL
mcs Consumer.cs -r:MyLibrary.dll -out:Consumer.exe

8.7 Running the compiled .exe on Windows (outside WSL)

Compiling in WSL produces a .exe that targets the .NET/Mono runtime — it is not a native Windows binary, and it will not run on Windows by itself. Two things are needed:

1. Install a runtime on the Windows machine

Pick one:

  • Mono runtime for Windows — install the Mono for Windows package so .exe files built with mcs can run via the Mono runtime. After install, you can either double-click the .exe (Mono associates itself with .exe files) or run it explicitly:
  mono programwin.exe
  • .NET Framework / .NET runtime — for simple GTK#-free console apps, the .exe may also run under an installed .NET runtime, but GTK# apps specifically require Mono's GTK# libraries, so the Mono for Windows install is the reliable option.

2. Copy the required DLLs alongside the .exe

Your compiled .exe references managed DLLs at runtime (not just at compile time). Anything you referenced with -r: or -pkg: must physically travel with the .exe:

  • Any custom library you built, e.g. MyLibrary.dll or MyGtkWidgets.dll
  • GTK# binding assemblies your app depends on (typically already provided by installing Mono for Windows, since it bundles the GTK# runtime — but if you used a nonstandard package, copy its DLL too)
  • Your .glade file, if the app loads one via Builder("myui.glade") — this isn't a DLL but is just as required; it must sit next to the .exe at the same relative path your code expects

Minimum folder layout to copy over to Windows: programwin.exe MyLibrary.dll (any custom DLLs you referenced with -r:) myui.glade (if using Glade)

Common pitfall: a program that runs fine in WSL but fails on Windows with FileNotFoundException or Could not load file or assembly almost always means a referenced DLL (or the .glade file) wasn't copied over, or Mono for Windows isn't installed.


9. Common Errors & Fixes

ErrorCauseFix
File does not contain a valid CIL imageRan mono on .cs source instead of compiled .exeCompile first: mcs file.cs, then mono file.exe
CS0246: type or namespace 'Gtk' could not be foundMissing package reference during compileAdd -pkg:gtk-sharp-3.0 to mcs command
CS0103: name 'Console' does not existMissing using System;Add using System; at top of file
Unable to locate package gtk-sharp2Package dropped in Ubuntu 24.04Use gtk-sharp3 instead
DllNotFoundException: libgdiplusCode uses System.Drawing without the lib installedsudo apt install libgdiplus
Could not load file or assembly 'MyLibrary.dll'DLL not in same folder / not foundPlace DLL next to the .exe, or set MONO_PATH
FileNotFoundException / Could not load file or assembly (on Windows)Runtime not installed, or referenced DLL/.glade not copied alongside the .exeInstall Mono for Windows; copy all -r: DLLs and .glade files into the same folder as the .exe

10. Notes on Alternatives

GTK# is a legacy, lightly-maintained binding. For new projects, consider:

  • Avalonia UI — modern, XAML-based, cross-platform, actively maintained
  sudo apt install dotnet-sdk-8.0
  dotnet new install Avalonia.Templates
  dotnet new avalonia.app -o MyApp

Use GTK#/Mono/Glade for legacy projects or learning; use Avalonia + dotnet for anything new and long-term.

Personal note:

Compile note: to compile the cs file mcs NAME_OF_THE_FILE.cs for GTK appilcation mcs -pkg:gtk-sharp-3.0 NAME_OF_THE_FILE.cs custom output name / windowed exe mcs -target:winexe -pkg:gtk-sharp-3.0 NAME_OF_THE_FILE.cs -out:CUSTOM_NAME.exe export as DLL mcs -target:library NAME_OF_THE_FILE.cs -out:CUSTOM_NAME.dll use a DLL in another program mcs Consumer.cs -r:CUSTOM_NAME.dll -out:Consumer.exe

to run note: same for all cases mono NAME_OF_THE_FILE.exe

OS

To test the application/setup across different Linux distributions, I used Ventoy to create a multiboot USB drive. Ventoy lets you copy multiple ISO files onto a single USB stick and choose which one to boot at startup, without needing to reformat or re-flash the drive for each OS.

Workflow

  1. Install Ventoy on the target USB drive.
  2. Copy the desired .iso files directly onto the Ventoy partition (no extraction needed).
  3. Boot from the USB, select the ISO from the Ventoy boot menu, and test the OS live or install it.

OS images checked

  • Fedora-Workstation-Live-44-1.7.x86_64
  • lubuntu-26.04-desktop-amd64
  • xubuntu-25.10-desktop-amd64

OS images to check

  • antiX-26_x64-full
  • xubuntu-26.04-minimal-amd64