I suppose it could be said that I'm a purist. Wizards, templates and helper utilies are great, but I believe before you become reliant upon these things you really ought to understand how they work. One problem that is presented to .NET Compact Framework developers is how to compile their code from the commmand-line, outside of Visual Studio. Using the piece of code below, I'm going to show you how you can simplify the process.
namespace HelloWorld
{
using System;
using System.Drawing;
using System.Windows.Forms;
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Label label1;
public Form1()
{
this.label1 = new System.Windows.Forms.Label();
this.label1.Location = new Point(10,20);
this.label1.Font = new Font("Arial", 14.25F, System.Drawing.FontStyle.Regular);
this.label1.ForeColor = Color.Red;
this.label1.Text = "Howdy!";
this.Controls.Add(this.label1);
this.MinimizeBox = false;
this.Text = "Hello World";
}
static void Main()
{
Application.Run(new Form1());
}
}
}
This is a simple piece of code; it merely creates a Windows Form and adds a label it.
When compiling C# code for the desktop version of the .NET Framework, you would invoke csc.exe. An example of using csc.exe is shown below:
csc /t:winexe /out:MyApp.exe /r:System.dll,System.Windows.Forms.dll MyApp.cs
This is how many books and websites tell us to compile our code. However, this can be simplified to the following:
csc /t:winexe MyApp.cs
The main difference here is that we are no longer explicitly linking to System.dll and System.Windows.Forms.dll -- or are we...? If you were to open Windows Explorer and go take a look at C:\Windows\Microsoft.NET\Framework\\ you will see a file called csc.rsp. Open this file in Notepad or the text editor of your choice and you will see the following:
# This file contains command-line options that the C#
# command line compiler (CSC) will process as part
# of every compilation, unless the "/noconfig" option
# is specified.
# Reference the common Framework libraries
/r:Accessibility.dll
/r:Microsoft.Vsa.dll
/r:System.Configuration.Install.dll
/r:System.Data.dll
/r:System.Design.dll
/r:System.DirectoryServices.dll
/r:System.dll
/r:System.Drawing.Design.dll
/r:System.Drawing.dll
/r:System.EnterpriseServices.dll
/r:System.Management.dll
/r:System.Messaging.dll
/r:System.Runtime.Remoting.dll
/r:System.Runtime.Serialization.Formatters.Soap.dll
/r:System.Security.dll
/r:System.ServiceProcess.dll
/r:System.Web.dll
/r:System.Web.Mobile.dll
/r:System.Web.RegularExpressions.dll
/r:System.Web.Services.dll
/r:System.Windows.Forms.Dll
/r:System.XML.dll
As the header in the file reads, the options specified in this file will be processed by csc.exe with every command-line compile. These are the default assembly references.
So this brings us to our first salient point:
- You must use the /noconfig option
But using the /noconfig option on its own is not good enough. We will have specify which assemblies we are referencing.
- You must explicitly reference ALL assemblies used by your application.
So far, our command line compile string looks like this:
csc.exe /t:winexe /noconfig /r:System.dll,System.Windows.Forms.dll MyApp.cs
However, this will still compile against the assemblies in the desktop .NET Framework. To ensure that we use the .NET Compact Framework assemblies, we have to provide the full path to the assemblies. If you use a default installation of Visual Studio .NET, these will be located in %VSROOT%\CompactFrameworkSDK\v1.0.5000\Windows CE\. Our compile command becomes:
csc.exe /t:winexe /noconfig /r:"C:\Program Files\Microsoft Visual Studio .NET 2003\CompactFrameworkSDK\v1.0.5000\Windows CE\System.dll","C:\Program Files\Microsoft Visual Studio .NET 2003\CompactFrameworkSDK\v1.0.5000\Windows CE\System.Windows.Forms.dll" MyApp.cs
This would be rather tedious to type out each time we compile. If you remember, we saw that the desktop framework uses a response file to define the default options. We can do the same for the .NET Compact Framework, and it will look something like this:
/nostdlib
/r:"C:\Program Files\Microsoft Visual Studio .NET 2003\CompactFrameworkSDK\v1.0.5000\Windows CE\mscorlib.dll"
/r:"C:\Program Files\Microsoft Visual Studio .NET 2003\CompactFrameworkSDK\v1.0.5000\Windows CE\System.dll"
/r:"C:\Program Files\Microsoft Visual Studio .NET 2003\CompactFrameworkSDK\v1.0.5000\Windows CE\System.Drawing.dll"
/r:"C:\Program Files\Microsoft Visual Studio .NET 2003\CompactFrameworkSDK\v1.0.5000\Windows CE\System.Data.dll"
/r:"C:\Program Files\Microsoft Visual Studio .NET 2003\CompactFrameworkSDK\v1.0.5000\Windows CE\System.Data.Common.dll"
/r:"C:\Program Files\Microsoft Visual Studio .NET 2003\CompactFrameworkSDK\v1.0.5000\Windows CE\System.Data.SqlClient.dll"
/r:"C:\Program Files\Microsoft Visual Studio .NET 2003\CompactFrameworkSDK\v1.0.5000\Windows CE\System.Data.SqlServerCe.dll"
/r:"C:\Program Files\Microsoft Visual Studio .NET 2003\CompactFrameworkSDK\v1.0.5000\Windows CE\System.Net.IrDA.dll"
/r:"C:\Program Files\Microsoft Visual Studio .NET 2003\CompactFrameworkSDK\v1.0.5000\Windows CE\System.Text.RegularExpressions.dll"
/r:"C:\Program Files\Microsoft Visual Studio .NET 2003\CompactFrameworkSDK\v1.0.5000\Windows CE\System.Web.Services.dll"
/r:"C:\Program Files\Microsoft Visual Studio .NET 2003\CompactFrameworkSDK\v1.0.5000\Windows CE\System.Windows.Forms.dll"
/r:"C:\Program Files\Microsoft Visual Studio .NET 2003\CompactFrameworkSDK\v1.0.5000\Windows CE\System.Windows.Forms.DataGrid.dll"
/r:"C:\Program Files\Microsoft Visual Studio .NET 2003\CompactFrameworkSDK\v1.0.5000\Windows CE\System.Xml.dll"
/r:"C:\Program Files\Microsoft Visual Studio .NET 2003\CompactFrameworkSDK\v1.0.5000\Windows CE\Microsoft.WindowsCE.Forms.dll"
If you look at the response file above, you will notice that the /nostdlib option is used and that an explicit reference to mscorlib.dll has been included. This is so that csc.exe does not attempt to reference the desktop version of mscorlib.dll.
This file is saved and then referenced in the compile command as follows:
csc /t:winexe /noconfig @C:\MyApp\cf_csc.rsp MyApp.cs
Note that we still have to explicitly specify the /noconfig option. If we include this in the response file, it will be ignored by the compiler.