diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..402d96e --- /dev/null +++ b/Readme.md @@ -0,0 +1,356 @@ +# Mono + GTK# + Glade — WSL Setup Guide + +## Table of Contents +- [1. Prerequisites](#1-prerequisites) +- [2. Install Mono](#2-install-mono) +- [3. Install GTK# (GTK# 3.0, for Ubuntu 24.04)](#3-install-gtk-gtk-30-for-ubuntu-2404) +- [4. Install Glade (visual UI designer)](#4-install-glade-visual-ui-designer) +- [5. Optional: libgdiplus (only if using System.Drawing)](#5-optional-libgdiplus-only-if-using-systemdrawing) +- [6. Compiling & Running](#6-compiling--running) +- [7. Minimal Working Examples](#7-minimal-working-examples) +- [8. Custom Output Names, Targets & Exporting DLLs](#8-custom-output-names-targets--exporting-dlls) +- [9. Common Errors & Fixes](#9-common-errors--fixes) +- [10. Notes on Alternatives](#10-notes-on-alternatives) + +--- + +## 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: +```bash +echo $DISPLAY +``` +Should return something like `:0`. If empty, GUI apps won't display. + +--- + +## 2. Install Mono + +```bash +sudo apt update +sudo apt install mono-complete +``` + +Verify: +```bash +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. + +```bash +sudo add-apt-repository universe +sudo apt update +sudo apt install gtk-sharp3 +``` + +Verify the package is registered: +```bash +pkg-config --list-all | grep gtk-sharp +``` +Expected output: +gtk-sharp-3.0 Gtk - Gtk +--- + +## 4. Install Glade (visual UI designer) + +```bash +sudo apt install glade +``` + +Launch it: +```bash +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): + +```bash +sudo apt install libgdiplus +``` + +--- + +## 6. Compiling & Running + +### Plain console C# program +```bash +mcs myprogram.cs +mono myprogram.exe +``` + +### GTK# 3.0 program (no Glade) +```bash +mcs -pkg:gtk-sharp-3.0 myapp.cs +mono myapp.exe +``` + +### GTK# 3.0 program using a Glade file +```bash +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) +```csharp +using System; + +class Hello { + static void Main() { + Console.WriteLine("Hello from Mono in WSL!"); + } +} +``` +```bash +mcs hello.cs +mono hello.exe +``` + +### Hello World (GTK# window, no Glade) +```csharp +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(); + } +} +``` +```bash +mcs -pkg:gtk-sharp-3.0 gtkcheck.cs +mono gtkcheck.exe +``` + +### Loading a UI built in Glade +```csharp +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(); + } +} +``` +```bash +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 +```bash +mcs -pkg:gtk-sharp-3.0 Program.cs -out:MyCustomApp.exe +``` +Run it the same way: +```bash +mono MyCustomApp.exe +``` + +### 8.2 `-target` options +| Target | Produces | Notes | +|---|---|---| +| `exe` (default) | Console executable | Shows a console window when run on Windows | +| `winexe` | Windows GUI executable | No console window — correct choice for GTK#/Glade GUI apps distributed on Windows | +| `library` | `.dll` class library | No `Main` entry point required to run directly; used by other programs | +| `module` | `.netmodule` | Rarely used; for combining into a single assembly later | + +Your example, building a windowed GUI executable with a custom name: +```bash +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: + +```bash +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: +```csharp +// MyLibrary.cs +namespace MyLib { + public class Greeter { + public string Greet(string name) => $"Hello, {name}!"; + } +} +``` +Compiled with: +```bash +mcs -target:library MyLibrary.cs -out:MyLibrary.dll +``` + +Then in a separate consumer program: +```csharp +// 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:`: +```bash +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): +```bash +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: +```bash +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: +```bash +mcs -pkg:gtk-sharp-3.0 ConsumerApp.cs -r:MyGtkWidgets.dll -out:ConsumerApp.exe +``` + +### 8.6 Quick reference +```bash +# 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](https://www.mono-project.com/download/stable/) 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: +```powershell + 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 + +| Error | Cause | Fix | +|---|---|---| +| `File does not contain a valid CIL image` | Ran `mono` on `.cs` source instead of compiled `.exe` | Compile first: `mcs file.cs`, then `mono file.exe` | +| `CS0246: type or namespace 'Gtk' could not be found` | Missing package reference during compile | Add `-pkg:gtk-sharp-3.0` to `mcs` command | +| `CS0103: name 'Console' does not exist` | Missing `using System;` | Add `using System;` at top of file | +| `Unable to locate package gtk-sharp2` | Package dropped in Ubuntu 24.04 | Use `gtk-sharp3` instead | +| `DllNotFoundException: libgdiplus` | Code uses `System.Drawing` without the lib installed | `sudo apt install libgdiplus` | +| `Could not load file or assembly 'MyLibrary.dll'` | DLL not in same folder / not found | Place 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 .exe | Install 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 +```bash + 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 \ No newline at end of file diff --git a/ReadmeQuick.md b/ReadmeQuick.md new file mode 100644 index 0000000..f227bb0 --- /dev/null +++ b/ReadmeQuick.md @@ -0,0 +1,17 @@ +### 8.6 Quick reference +```bash +# Console exe, custom name +mcs Program.cs -out:myapp.exe + +# Console exe, custom name +mcs -pkg:gtk-sharp-3.0 Program.cs -out:programwin.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 +``` diff --git a/dll/atk-sharp.dll b/dll/atk-sharp.dll new file mode 100644 index 0000000..cb11a7b --- /dev/null +++ b/dll/atk-sharp.dll Binary files differ diff --git a/dll/cairo-sharp.dll b/dll/cairo-sharp.dll new file mode 100644 index 0000000..ae71a7a --- /dev/null +++ b/dll/cairo-sharp.dll Binary files differ diff --git a/dll/gdk-sharp.dll b/dll/gdk-sharp.dll new file mode 100644 index 0000000..08f0654 --- /dev/null +++ b/dll/gdk-sharp.dll Binary files differ diff --git a/dll/gio-sharp.dll b/dll/gio-sharp.dll new file mode 100644 index 0000000..818134d --- /dev/null +++ b/dll/gio-sharp.dll Binary files differ diff --git a/dll/glib-sharp.dll b/dll/glib-sharp.dll new file mode 100644 index 0000000..f480530 --- /dev/null +++ b/dll/glib-sharp.dll Binary files differ diff --git a/dll/gtk-sharp.dll b/dll/gtk-sharp.dll new file mode 100644 index 0000000..ece3ff2 --- /dev/null +++ b/dll/gtk-sharp.dll Binary files differ diff --git a/dll/pango-sharp.dll b/dll/pango-sharp.dll new file mode 100644 index 0000000..07fc422 --- /dev/null +++ b/dll/pango-sharp.dll Binary files differ