WindowsDevCenter.com
oreilly.comSafari Books Online.Conferences.

advertisement


AddThis Social Bookmark Button

Porting a Project from Visual Studio .NET to Mono

by Kevin Farnham
06/13/2005
Use ClickOnce to Deploy Windows Applications

Three years ago, when .NET was still in pre-release status, I developed a C# application to automatically generate stock market web pages for my website. The .NET framework and C# language were appealing because they seemed to provide a rich feature set and capability for developing complex software relatively quickly.

The application was developed in June-August 2002 using a pre-release version of Visual Studio .NET. The program retrieves historical price and volume information for a selected set of stocks from the internet, performs statistical analyses, and generates web pages that include tables and graphs analyzing the performance of the stocks. Here's the original user interface:

VS NYA Reader

Due to an increased paid workload, the project was set aside, its C# source file date-stamped 08/13/2002.

The Experiment

Three years later, the computing world has changed dramatically. I'm again working on the website, developing in a Debian Linux environment, and I'd still like to add stock market analysis. I'd read some news about the Mono Project, and briefly browsed the website.

I decided: why not give Mono a test drive by porting the 2002 Visual Studio .NET stock market application to Mono? Doing so would give me an opportunity to assess Mono's capabilities, quirks, and deficiencies, enabling me to better judge if I want to use Mono for future development. So I launched into it.

It turns out that Mono runs only on the experimental version of Debian Linux ("Sid"). I had a spare computer available, so I loaded Debian Testing ("Sarge") onto it, and used apt-get upgrade to upgrade the operating system to "Sid." Next, I used the Debian apt-get package manager to install Mono and MonoDevelop. Executing mono --version and monodevelop --version showed me that the programs were successfully installed and that I was working with Mono Version 1.0.5 and MonoDevelop Version 0.5.1.0. I copied the C# source file from my Windows machine to my Debian "Sid" box, and I was ready to begin the experiment.

What Worked (75 Percent) and Didn't Work (Missing Namespaces)

To a developer familiar with Mono's status, a glance at the first few lines of my original Visual Studio C# file would immediately identify the major porting problems I encountered:

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Net;
using System.Text;

But for me this was an adventure! I opened a terminal, changed into my source directory, entered mcs StockMkt.cs, and read my first Mono compiler error message:

Can't find "System.Windows.Forms.Form"

A bit of research later, I found that Windows.Forms is an ongoing development activity in the Mono community. Further on, when I tried compiling the functions that make graphs and dump them to image files, I found that the System.Drawing namespace is also not supported in Mono 1.0.5. Missing namespaces were about as fundamental a problem as I could have encountered. While the user interface is not a critical feature of the program (command-line arguments could suffice), the plot images are quite important.

The good news is that, despite the missing namespaces, about 75 percent of the original Visual Studio .NET code ported into Mono with no modification required. These segments of code address functions such as downloading stock market data from the internet, writing and reading binary and text files containing the downloaded data, performing statistical calculations using arrays of data, and generating the web pages that display statistics about the stocks. Almost all of this type of code--data manipulation, numeric computation, stream/file reading and writing--ported directly into Mono with no modification required. That this could happen with code that was developed three years ago using a pre-release version of Visual Studio .NET is quite remarkable, in my opinion.

A Few Quirks

Related Reading

Mono: A Developer's Notebook
By Edd Dumbill, Niel Bornstein

During the course of the porting, I encountered a few quirks and idiosyncrasies. This is to be expected, since Mono is a work in progress. Here are a few of the issues I encountered:

  • The DateTime.Parse function did not recognize dates in the format "24-May-05." I made a conversion function that formatted the dates into MM-DD-YYYY format, which parsed correctly.
  • switch statements were sometimes quirky: in a few places they failed to compile for no apparent reason, and I ended up replacing them with if/else blocks.
  • Application.Exit() was not recognized; this had to be replaced with the Mono statement System.Environment.Exit().
  • The "x" icon on the GUI sometimes closed the window but left a dangling process running; I added an Exit button that calls System.Environment.Exit() to make sure the application completely exits.

An annoying idiosyncrasy is inconsistent line numbering between MonoDevelop and the mcs compiler. MonoDevelop labels the first line of code "Line 1." The compiler seems less rule-bound. Coupled with the sometimes obscure error messages produced by the Mono compiler, finding the actual location of trivial bugs becomes more tedious than we'd like.

Hacks and Future Necessities

Because of the missing Windows.Forms namespace, I had little alternative but to start my port from a "Hello World!" type of base. I needed to make something that would compile and run within Mono; then I would add the specific StockMkt.cs functions one by one.

The user interface is a relatively minor part of the original application: a set of Windows.Forms buttons, a few NumericUpDown widgets, a ListBox, and a ProgressBar. I did some research on Gtk and, starting with an example from Mono: A Developer's Notebook, I programmed a basic GUI consisting of a Gtk Window containing a vertical button box (VButtonBox), into which I placed buttons for launching each program function. I commented the progress bar code and temporarily substituted hard-coded numbers wherever a NumericUpDown widget was required. I eliminated the ListBox by limiting the ported application to only the S&P500 stocks.

With Gtk code in the program, my required compile statement became:

mcs -pkg:gtk-sharp StockMkt.cs

I executed this, the compile succeeded, and when I entered mono StockMkt.exe my new pared-down Mono GUI was up and running:

Stock Market GUI

I didn't port the "Download Quotes" function because it was incomplete in the original program. The "Exit" button was added to explicitly shut down the application, after I found that clicking the "x" sometimes closed the window but left a process running in the background.

Did the Port Succeed?

The most important capability of the StockMkt.cs program was the drawing of plots for the web page for each stock. The plots included parameters calculated based on the historical pricing of each stock, for example, volatility over the trailing N days. As far as I know, this information is not available on the internet, and represents a primary innovative contribution the software could make to the investing community. Since none of the graphics drawing and imaging code could be ported, the application cannot be said to have been fully "ported."

I investigated a few third-party libraries to address the graphics drawing image problem, but nothing seemed to provide a quick and easy solution. For the moment, I am giving something back to Yahoo (the historical data was downloaded from their site) by replacing the unavailable images with a link to the Yahoo! Finance Basic Chart for each stock.

As a mid-term solution, I'll adapt existing Perl code that applies the GD graphics library, accessing it using Lincoln Stein's GD.pm CPAN module, to produce PNG image files. I'll use XML to pass the data between the Mono and Perl programs. Then, later on, I'll be able to apply an XSL to transform the XML into an SVG file.

Conclusions

Mono is a work in progress. New features and capabilities are being developed every day. Importantly, licensing issues that have threatened the long-term viability of the project are being addressed.

Large segments of the C# code that was originally developed on Visual Studio .NET in 2002 compiled without change. The lack of Windows.Forms is not a significant problem for the tested StockMkt.cs application, since its user interface is minimal. The missing System.Drawing namespace is critical, since the test StockMkt.cs application's primary intended output is graphical plots stored as PNG files.

Significant work is underway in the Mono development community on Windows.Forms capability, and work is also proceeding on the System.Drawing namespace. Mono version 1.1.7, released May 4, includes significantly extended Windows.Forms support. Windows.Forms in Mono is implemented using System.Drawing, so their development is proceeding hand-in-hand. See the Mono System.Windows.Forms page for details.

The achievements of the Mono development community to date are very impressive. Since Mono's current data access, data management, and XML capabilities are already so well-developed, my plan is to continue developing the StockMkt.cs application using Mono.

Related Links

The following links provide information on the current state of Mono and its future:

Kevin Farnham is the owner of Lyra Technical Systems, Inc, a small consulting and publishing company.


Return to OnDotNet.com