Porting a Project from Visual Studio .NET to Monoby Kevin Farnham
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:
Due to an increased paid workload, the project was set aside, its C# source file date-stamped 08/13/2002.
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
mono --version and
--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
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
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
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:
DateTime.Parsefunction 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.
switchstatements were sometimes quirky: in a few places they failed to compile for no apparent reason, and I ended up replacing them with
Application.Exit()was not recognized; this had to be replaced with the Mono statement
- 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
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
functions one by one.
The user interface is a relatively minor part of the original application: a
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 (
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
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
StockMkt.exe my new pared-down Mono GUI was up and running:
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
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.
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
capability, and work is also proceeding on the
System.Drawing namespace. Mono
version 1.1.7, released May 4, includes significantly extended
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
application using Mono.
The following links provide information on the current state of Mono and its future:
- Mono Project website
- MonoDevelop website
- Mono Project Roadmap: High-level plan and tentative schedule for upcoming Mono releases
- Novell Customer Showcase: City of Munich: A Mono success story, describing the porting of a substantial existing C++/VB/.NET application to Mono
- Mono: A Developer's Notebook: A superb reference
- Mono StockMkt.exe Results: example website produced by the StockMkt application
- The original Visual Studio .NET code described in the article
- The Debian Mono Port code that produced the example web results
- "Will Mono Become the Preferred Platform for Linux Development?": interesting information on the Mono licensing dilemma and Mono's future
- "The Future of Mono": provocative opinion and analysis
Return to OnDotNet.com