posted by Joao Manuel Moura Paredes on Wed 21st Apr 2004 20:06 UTC
IconThis article focus on programming in C# with Mono. It contains a compilation of extremely useful tips and workarounds, especially for people used to lower level programming, like C programmers. Since the Mono documentation is still far from finished, and I found from my experience that it is still very hard to find information and help with C# issues when using Mono, I compiled a series of tips that I gathered from my experience with Mono.

1st Tip: Another good place to find information.

For most of the people out there, this will save them a few bucks in buying books about C# or a few trips to the public library. For others, this will just save them a few hours Googling. Many of you will find yourselves in the same situation: I only had a IDE (Kate, in my case), Mono and Monodoc. Well, I had Google too. Monodoc is not bad, but is rather insufficient. It is extremely incomplete. So, I found myself peeking at the MSDN site, where they have all the class docs. Here is a direct link for the class docs.

Note: Before you attempt to use any class, method or property, you should check monodoc first. Why? Because even though monodoc does not document everything, it has the pointers to every implemented class, method and property. Even though it does not explain every one of them, it will tell you if they are implemented, not implemented or incomplete. If you come to use XML with your Mono program, you will notice, when you take a look at monodoc, that a few methods and properties in the most important XML classes are not implemented. I'm talking about XmlDocument.GetElementById, for example. This method is marked unfinished and actually, it is. I was not paying much attention to monodoc when I tryed to used it, and I wondered for hours why my program kept crashing with null pointer exception in the call to that method. Then, when "re-browsing" monodoc I noticed the Unfinished tag. I tryed to get a workaround for this. Well, I coudn't. At least, I didn't try hard. So beware, that there are a lot of unfinished methods around.

2nd Tip: Before starting to use Mono.

Before starting to use Mono, there is a special tweak you can prepare if you use Linux and have superuser permissions on the machine. I allways found it anoying having to type mono programname.exe everytime I want to run a .Net program. So, I used a trick, that takes advantage of a Linux kernel feature (if you're used to compiling the kernel, its the Misc Binary Format Support). Remember that you MUST have support for it in the kernel (in general, the distributions come with support for Misc Binary Format activated, but if not, you will have to recompile the kernel).
This trick allows me to call a program just typing ./programname.exe (if you're using BASH, you won't have to type much :)). When you're root, edit your /etc/fstab and add the following line

none /proc/sys/fs/binfmt_misc binfmt_misc defaults 0 0

With this line, the binfmt_misc virtual filesystem will be mounted in /proc, and you will be able to instruct the kernel to interpret different binary file formats. I believe Java programmers have been using this, and some distributions used to come preconfigured to suport this for use with Wine, to allow a user to easily run Win32 binaries. Now that you've edited fstab, you need to mount the filesystem. Just run this in your shell:

mount /proc/sys/fs/binfmt_misc

Don't worry, you will not need to run this everytime you're computer boots because it is already in your fstab. Next time your computer boots it will mount it "automagically". Now, you have to tell the kernel that there is a special kind of binaries he has to be aware of, and that there is a proper interpreter for them. You can do that by executing the following line in your shell, as root, of course:

echo ':CLR:M::MZ::/opt/gnome/bin/mono:' > /proc/sys/fs/binfmt_misc/register

Notice that you have an MZ in that line. MZ is the identifier for executables in Microsoft OS's. That MZ stands for Mark Zbikowsky, if i'm not mistaken, which was the responsible for the creation of the original EXE format. For those of you using this trick with Wine, some of you may have noticed that this can interfere with Wine and cause conflicts. There are ways of going around this, although I'm not discussing them here.
Once you've done this, try running a .Net program in your shell, just by calling it's name: ./programname.exe. Didn't it work nice? If you do not want to have to type this command every time your computer reboots, you should add it to your /etc/rc.d/rc.local (actual file and path may vary across distributions).

3rd Tip: Executing external programs (shelling).

One of the things I needed to do in a small program I made, was to be able to execute an external command. I searched all the Monodoc info, and even went to MSDN. But, I had little luck understanting. I finally found somewhere where it was explained how to do it. Use the following code:

System.Diagnostics.Process proc = new System.Diagnostics.Process(); // (1)
proc.EnableRaisingEvents=false; // (2)
proc.StartInfo.FileName= "ls"; // (3)
proc.StartInfo.Arguments = "-lh"; // (4)
proc.Start(); // (5)
proc.WaitForExit(); // (6)

if(0 != proc.ExitCode) Console.WriteLine("Error"); // (7)

The code is very easy to understand. You create an object of the Process class of assembly System.Diagnostics (1), you let him know you don't want any events raised (2) and you let him know the command (3) and the arguments (4). Then you tell him to start executing the program (5) and to wait for its completion (6). When complete, you can test the exit code for errors (7). How different can it be from system("ls -lh");? ;)

Table of contents
  1. "Tips for Mono, Page 1/2"
  2. "Tips for Mono, Page 2/2"
e p (0)    60 Comment(s)

Technology White Papers

See More