Copyright (c) 2004 by Charlie
Calvert
This article describes how to get the still experimental .NET C# code for Windows.Forms running
under Linux using Mono.
Mono is an open source implementation of Microsoft .NET that runs on
Windows, Linux and various Unix platforms. Windows.Forms, sometimes
called WinForms, is a the technology that Microsoft .NET and Mono
use to describe the code needed to create GUI applications that run in
a window. Windows.Forms is distinct from the WebForms technology
used to create applications that run in a browser. A typical
minimal Windows.Forms application would have a main Window, and a few
controls such as buttons, list boxes, edit controls, menus, etc.
In the
opening section of this article you will read how to compile and run a
very
simple Windows.Forms application on Windows. The next step is to get
the same application compiled and running on Linux. The article ends
with a description of how to get a default C#Builder or Visual Studio
Windows.Forms application running under Mono on either Linux or Windows.
Mono Based Windows.Forms on Windows
Running Windows.Forms on Windows is very simple. After performing Mono's
forehead install described in a previous article, you should test
to make sure the Mono compiler, called MCS,
is on your path. To perform this test, type mcs --about at a command
prompt. If this command produces sensible output referencing the
Mono compiler, then all is well. If not, refer to the install
article. If all is well, the output might look something like this:
[d:documentsdocstecharticleslinuxmono]mcs --about
The Mono C# compiler is (C) 2001, 2002, 2003 Ximian, Inc.
The compiler source code is released under the terms of the GNU GPL
For more information on Mono, visit the project Web site
http://www.go-mono.com
The compiler was written by Miguel de Icaza, Ravi Pratap and Martin Baulig
Assuming Mono is installed correctly, you can now use Borland C#
Builder, a text editor, or
Visual Studio to create a simple program such as the following, and
place it in a file called HelloWindowsForms.cs:
class HelloWindowsForms
{
static void Main()
{
System.Windows.Forms.MessageBox.Show("Welcome to the bill free zone.");
}
}
When compiled and executed, class HelloWindowsForms
produces output
like that shown in Figure 1.
Figure
1: A simple C# .NET GUI application running under Linux. It looks about
the same on Windows XP.
To compile the program shown above, create a simple batch file
called build.bat consisting of
the following code:
mcs HelloWindowsForms.cs /r:System.Windows.Forms.dll /r:System.Drawing.dll
This command says that you want to compile HelloWindowsForms.cs,
and reference the assemblies
(libraries) called System.Windows.Forms.dll
and System.Drawing.dll. These
libraries are built into both Mono and Microsoft .NET. They contain code that resolves the
references needed by the linker. More particular, they are needed by
this program because they contain code for popping up a MessageBox.
Run the batch file from the command line to produce HelloWindowsForms.exe:
[d:srccsharpwindowsformshelloworld]build.bat
mcs HelloWindowsForms.cs /r:System.Windows.Forms.dll /r:System.Drawing.dll
Compilation succeeded
[d:srccsharpwindowsformshelloworld]dir
Volume in drive D is ChasDiskD Serial number is 4D89:2760
Directory of D:srccsharpWindowsFormsHelloWorld*
4/18/04 11:50 <DIR> .
4/18/04 11:50 <DIR> ..
4/18/04 11:50 <DIR> CVS
4/02/04 15:43 76 build.bat
4/18/04 11:50 92 build.sh
4/18/04 11:50 151 HelloWindowsForms.cs
4/18/04 16:30 3,072 HelloWindowsForms.exe
3,391 bytes in 4 files and 3 dirs 16,384 bytes allocated
25,358,868,480 bytes free
You can run the executable simply by typing its name: HelloWindowsForms.exe, at the DOS
prompt. This command will run your code under the Microsoft
.NET framework, assuming that the framework is installed. If it is
not installed, and you want to install it, launch Internet Explorer and
choose Tools | Windows Update
from its menu. Then follow the prompts to install the .NET framework.
If the framework is not available as an install item, then it is
probably already on your system. If you are in doubt about the state of
.NET on your system, check to see if the following directory is
present: C:WINDOWSMicrosoft.NETFramework.
If that directory exists, then the framework is probably installed. For
further help, see the appropriate
URL at the Microsoft web site.
Note that I ran my code against the .NET Framework 1.1, found in this
directory: C:WINDOWSMicrosoft.NETFrameworkv1.1.4322
If you are using Windows, but don't want to run your program under
Microsoft's CLR, you can run your application under Mono, by typing: mono HelloWindowsForms.exe. The
output from this command should be approximately the same as what you
see when running directly under the Microsoft .NET framework.
At this stage you should have a simple Windows application that uses
Windows.Forms up and running.
Before showing an example of getting a more complex program up and
running, I want to stop and talk about getting the HelloWindowsForms
program running under Linux. If you are uninterested in Linux, you can skip ahead to the more complex example.
Mono Setup Issues on Linux
Before reading further, you should make sure you have an up to date
version of Mono on your Linux system. The Mono install process was
described in an article I
wrote in early April, 2004. Please refer to that article if you are
not sure that you have the latest version of Mono installed on your
system.
A proper installation of Mono should include Wine. Wine is a set of libraries and
related tools that allow you to run Windows applications on Linux. As
the result of a complicated technical decision, Wine is used to support
the portions of Mono that include Windows.Forms. It is not, as far as I
know, used in any other part of Mono.
I have added some additional notes here to help you double check
that you have installed everything you need. Before attempting to
run Windows.Forms on Linux,
you need to be sure that you have WineLib installed. If it
is not properly installed, you are likely to get something like the
following error:
Could not load winelib.exe.so
This error is likely to be encountered by many developers because
WineLib is not, as of April 2004, distributed via RedCarpet.
RedCarpet is a tool frequently recommended to help you install Mono on
your Linux system. Because WineLib is not part of the Red Carpet
install process, I had to manually download a copy of winelib-0.1.tar.gz.
Though I have not done so personally, I believe you can also get it
from CVS.
After retrieving the compressed tar file, I then decompressed it,
extracted its contents, and then compiled and installed WineLib, by
entering these commands at a shell prompt:
tar xvfz winelib-0.1.tar.gz
cd winelib-0.1
./configure -prefix=/usr
make
su -c "make install"
Note that the last command requires that you enter the root password for your system. The
end result of this is the production of winelib.exe.so. If you have done a
standard install of Wine and Mono using RedCarpet, then
you will want to insure that the call to "make install" put winelib.exe.so in the directory
called /usr/lib. Because you
added -prefix=/usr when
calling configure, the above code should install the file directly in /usr/lib. If you typed simply ./configure, with no prefix
argument, then the file will be placed in /usr/local/lib. If the file is not in /usr/lib, you may need to become
root and manually copy the file to the correct location. If you did not
install Mono via RedCarpet, but instead instead built Mono from source,
then /usr/local/lib is
possibly the best place for you to install the file.
Another potential problem you can have with the default RedCarpet
set up is that wineserver may
not be able to run correctly on your system. By default, wineserver
does not have to be running. Mono should start wineserver whenever it
is needed. But if you are having trouble running Windows.Forms, or any Wine application, then you should
check that wineserver is
running correctly. Here is how to check if wineserver is in memory:
ps -C wineserver
The output should look something like this:
PID TTY TIME CMD
21763 ? 00:00:00 wineserver
If you are able run wine applications correctly, and you don't see
wineserver in memory when you
run ps -C wineserver, then
don't panic,
everything is fine. But if you are having trouble with Wine or Mono,
and if you don't see output similar to this, then become root and try
starting wineserver by typing
the word wineserver
at the command prompt. Now try typing the ps -C wineserver command a
second time. You should see wineserver
listed as being in memory.
If things aren't working for you, please reread my install
document, paying particular attention to the information on winesetuptk.
You can remove a program like wineserver from memory using the kill
command: kill -9 21763, where 21763 is the pid you see when you
running
ps-C wineserver. This number
will change nearly every time wineserver is loaded into memory.
To confirm that you have Wine installed properly, trying typing notepad or sol at the Linux shell prompt. If
Windows Solitaire or Notepad pop up, then all is probably well. You can
also try copying a simple Windows application such as Notepad.exe or Solitaire (Sol.exe, cards.dll) from a copy of
Windows to your Linux system and see if it runs when you type wine Notepad.exe.
Windows.Forms under Mono on Linux
If you have Wine and Mono installed properly on your Linux system,
you should be able to compile and run the following simple
Windows.Forms program:
class HelloWindowsForms
{
static void Main()
{
System.Windows.Forms.MessageBox.Show("Welcome to the bill free zone.");
}
}
To compile the program, use a text editor to create the following
script, which I called build.sh:
#! /bin/bash
mcs HelloWindowsForms.cs /r:System.Windows.Forms.dll /r:System.Drawing.dll
If you have KDE installed, there should be an editor called kate installed on your system. Kate
is a powerful editor which provides most of the tools you need to
create source files by hand. If you prefer, you can use vi or emacs.
And of course, since you now have wine installed, you can use notepad
if you are so inclined.
You can run the script by typing sh
build.sh. If all is going well, you should now be able to run
the program by typing the following command:
mono HelloWindowsForms.exe
This should produce the output shown in Figure 1.
If you are having troubles, go back and read the previous section,
or the article
referenced above about installing Mono on Linux. If you
are still having trouble, try reading one of the mono mailing lists.
Standard C#Builder or Visual Studio
Windows Forms on Linux
You are now ready to create a somewhat more complex application,
just to see that such things are possible. For instance, the program
shown in Figure 2 was created on Windows and yet runs
on Linux. You can see the code for the program in Listing 1.

Figure 2: This
program is a slightly modified default C#Builder or
Visual Studio program running under Mono on Linux.
To create this program, open up C#Builder or Visual Studio, create a
default Windows application, and modify its InitializeComponents method
as follows:
private void InitializeComponent()
{
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.BackColor = System.Drawing.Color.Red;
this.ClientSize = new System.Drawing.Size(380, 150);
this.Name = "Form1";
this.Text = "Form1";
this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
}
Next create a paint event handler and modify the method so that it
looks
like
this:
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
Graphics g = e.Graphics;
Rectangle rect = new Rectangle(20, 30, 100, 50);
g.FillRectangle(new SolidBrush(Color.FromArgb(255, 0, 255, 0)), rect);
rect.X += 160;
g.FillEllipse(new SolidBrush(Color.FromArgb(255, 255, 255, 255)), rect);
SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(255, 255, 255, 0));
g.DrawString("Built in Windows, runs on Linux",
new Font("Verdana", 14), semiTransBrush,
new RectangleF(20, 100, 375, 100) );
// Dispose
g.Dispose();
}
Now go to the command prompt in either Linux or Windows and create a
batch file called
build.bat or build.sh that contains the following command:
mcs /out:WindowsApplication1.exe AssemblyInfo.cs Form1.cs /r:System.Windows.Forms.dll /r:System.Drawing.dll
In Windows, you can simply type
WindowsApplication1.exe at the
command prompt to run the program. On Linux, you should type mono WindowsApplication1.exe at the
shell prompt to run the program. Note that this code to compile the
program references three assemblies, and uses the out flag to specify the name of the
executable that you want to create.
The entire source code for the application is shown in Listing 1.
The output from
the program on Windows is shown in Figure 3. Note that the background
is drawn correctly in Windows, but not in Linux:
this.BackColor = System.Drawing.Color.Red;
Though this bug may be
fixed by the time you read this article, I've made no attempt to avoid
it so that you can understand the Mono is still a work in progress. I
hope you also notice, however, that the drawing commands in the Paint
method do work correctly. The basic controls, such as list boxes, edit
controls, and buttons, also work correctly on both platforms. You
can see this in Figures 4 and 5, which are found at the end of the
article, after Listing 1.

Figure 3: The
WindowsApplication1.exe running on Windows.
Listing 1: A default
C#Builder or Visual Studio Program.
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
//using System.Data;
namespace WindowsApplication1
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.BackColor = System.Drawing.Color.Red;
this.ClientSize = new System.Drawing.Size(380, 150);
this.Name = "Form1";
this.Text = "Form1";
this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
Graphics g = e.Graphics;
Rectangle rect = new Rectangle(20, 30, 100, 50);
g.FillRectangle(new SolidBrush(Color.FromArgb(255, 0, 255, 0)), rect);
rect.X += 160;
g.FillEllipse(new SolidBrush(Color.FromArgb(255, 255, 255, 255)), rect);
SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(255, 255, 255, 0));
g.DrawString("Built in Windows, runs on Linux",
new Font("Verdana", 14), semiTransBrush,
new RectangleF(20, 100, 375, 100) );
// Dispose
g.Dispose();
}
}
}
Figure 4: One of the Mono
Windows.Forms programs used used by the development team for testing
the Mono framework. The program is shown running on Linux.
This one tests buttons.
Figure 4: One of the Mono Windows.Forms programs used
for testing the Mono framework. The program is shown running on Linux.
This one test the text control.
Summary
In this article you have learned how to compile and run a .NET
Windows.Forms application on Linux and
Windows. You saw that using Mono on Windows is a simple
process involving nothing more than running a simple install, then
entering some simple source code which can be easily compiled and
executed. Getting
the same program running on Linux can be just as simple, but usually
involves a considerably more complicated install. In particular, you
may need to do some extra work to ensure that WineLib is installed
correctly. But once you have Mono installed correctly, the process of
compiling and running the application is nearly identical to compiling
and running it on Windows.
Windows.Forms on Linux is definitely a work in progress. It is not
ready for use in a production system at this time. However, it is up
and running. Progress on its development can often be quite swift. With
a little luck, and good support from the open source community, it
should be ready for use in a short period of time.
Connect with Us