Monday, June 2, 2008

Hacking VS C# 2008 Express

VS C# 2008 Express is a really nice product in many ways - you've got most of the stuff you need, but most of all, it's free!

Though, I was playing around for it a bit, and needed to support compiling against a specific platform (x86 instead of Any CPU which is default). The reason for this was that, in my project, I was refering to a dll written in managed c++ - compiled for x86! Mixing x64 and x86 is never a good solution, and as C# projects per default compiles against Any CPU they will run in 64-bits mode on a 64-bit computer. When the application tries to load the 32-bit dll, the application crashes...

Now, in VS C# 2008 Express, you cannot specify another target platform but the Any CPU platform. Guess they think that "if you need support for specific platforms, you should be able to pay for a commercial version".

I was reading through MSDN, and found this note:
Note /platform is not available in the development environment in Visual C# Express.

"Damn", I thought, "this is the end. But what does development environment mean?". I had to try it out manually using the command prompt, so I compiled the project in VS and copied the command line output from the output window, being something like:
C:\WINDOWS\Microsoft.NET\Framework\v3.5\Csc.exe /noconfig /nowarn:1701,1702 ...
I put the line in a batch file, and added the /target:x86 flag, compiled it and... it worked! The project got compiled using x86 as a target platform.

As it turns out, VS C# 2008 Express does support the /target option, and probably others as well. They only lack the support for the option in the IDE, which is kinda a hacky way of disabling a feature, IMO.

Now, I don't want to build the project using a batch file every time, I would like to build it inside VS IDE so that others can easily build it. As the VS project files are nothing but XML, you can easily open them up in any editor you like to see their contents. I did this to find out if there was some way to add a target flag to the compiler, but unfortunately I couldn't find anything interesting (of course that would be too easy!). I continued with searching the web, and found this strange property:
CSharpProjectConfigurationProperties3.PlatformTarget Property
This member provides internal-only access to C# project configuration properties.
...
External components can access these properties through the Properties collection for the appropriate Visual Studio automation object.
"Well", I said to my self, "the Properties collection would probably refer to the XML properties found in the project file, so once again I opened up the project file, and browsed to two property groups being:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
and
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
In these groups, I added the PlatformTarget property:
<PlatformTarget>x86</PlatformTarget>
I saved the file, reloaded it in VS, recompiled the project... and viola, it worked! All you needed to do was to find out the magic property to add to the project file! :)

This proves that C# Express contains more under the hood than what's visible to the eye. With a simple editor, and some knowledge on how to search MSDN, you can get a lot out of this product!