← home

WinForms on Linux

Running a Windows Forms codebase on Ubuntu, Fedora, Debian and friends — what works, what to watch for, and how to ship it.

Why plain WinForms can’t do it

System.Windows.Forms ships only in the Windows Desktop runtime. On Linux there is no Microsoft.WindowsDesktop.App shared framework to resolve against, so a net10.0-windows project doesn’t merely fail to run — dotnet build refuses it. The assembly is a wrapper over user32.dll and GDI+, and neither exists here.

The three things people usually try:

What Majorsilence.Forms does instead

It reimplements the WinForms API on top of SkiaSharp and hosts it in an Avalonia window. On Linux that means a normal, native X11 application — a real window in your window manager, real input, GPU compositing where available, and a plain net10.0 build with no -windows suffix anywhere.

dotnet new install MajorsilenceForms.Templates
dotnet new majorsilenceforms
dotnet run

That is the whole setup on a stock Ubuntu box with the .NET SDK installed. The same source builds and runs unchanged on Windows and macOS.

What actually works on Linux

Area On Linux
Windowing, input, HiDPI Native, via the Avalonia X11 backend. Runs under XWayland on Wayland sessions.
Rendering SkiaSharp, GPU-accelerated — the same paint code as Windows and macOS, so controls look identical
Fonts and text SkiaSharp resolves system fonts through fontconfig; Majorsilence.Forms.Drawing.Common also bundles a fallback set, so text renders even on a minimal image with no fonts installed
GDI+ / System.Drawing code Replaced by Majorsilence.Forms.DrawingBitmap, Font, Pen, Brush, Region, Drawing2D, Imaging, and EMF/WMF playback
Common dialogs OpenFileDialog, SaveFileDialog, FolderBrowserDialog, ColorDialog, FontDialog work through the backend’s native dialogs
Printing PrintDocument renders through Skia to PDF rather than to a print driver — the same on every OS
WebView controls Real WebKitGTK, where WebKitGTK/WPE is installed
Sound Played through the OS utility (paplay/aplay)
Native window handle A real X11 XID via WindowBase.PlatformHandle (per-control handles are IntPtr.Zero everywhere — see Native interop)
UI Automation / screen readers Windows-only today (Majorsilence.Forms.WindowsUIAutomation); AT-SPI is not wired up. The backend-neutral automation tree still drives tests and Selenium on Linux
Majorsilence.Forms.WindowsFormsInterop Windows-only by definition — it hosts real System.Windows.Forms forms, which don’t exist here

Deployment notes

Nothing exotic — it’s an ordinary .NET application:

dotnet publish -c Release -r linux-x64 --self-contained

Two things worth knowing:

Verified on Linux

The Explorer sample — a Windows Explorer clone — runs on Ubuntu, and the full control gallery runs on the Avalonia backend there:

The Explorer sample running on Ubuntu

Next