Wednesday, August 24, 2005

Ant Humor

Was just reading the NAnt docs and ran across something funny: "The name NAnt comes from the fact that this tool is Not Ant." Since the Ant FAQ says that Ant is an acronym for "Another Neat Tool", NAnt is really an acronym for "Not Another Neat Tool". I wonder if they did that on purpose?

Wednesday, August 17, 2005

Running OpenNETCF 1.3 On NET PC

Since I'm porting a complex application framework from NET PC to NET CF I sometimes find it useful when debugging to run our NET CF code on the NET PC framework. This also comes in handy if, for instance, you want to run unit tests against your NET CF code on the desktop, since on-device automated testing is nearly impossible at this point. (There are sometimes major differences between the two implementations so this is not a good long-term strategy.)

The hardest part about this was getting OpenNETCF 1.3 to run on the desktop. Here's why: The OpenNETCF.Configuration.ConfigurationSettings class uses System.IO.Path internally when figuring out where to look for config files. It passes a Pocket PC compliant path string to Path.Combine() at one point, and, since the code is actually running on the NET PC framework, Path.Combine() throws an ArgumentException.

The only solution (short of rebuilding the OpenNETCF library) is to pre-install a different implementation of OpenNETCF.IConfigurationSystem before the default implementation is installed. There's no public API for installing your custom IConfigurationSystem; you must install it via reflection calls which bypass the restrictive access modifiers. (Obviously, this is a major hack not suitable for production code.) Here's an example of such an IConfigurationSystem implementation which simply passes configuration requests through to the standard NET PC ConfigurationSettings class:


using System;
using System.Reflection;
using ONETConfig = OpenNETCF.Configuration;
using MSConfig = System.Configuration;

namespace Test.PCUtil
{

public class PassThruConfigSystem : ONETConfig.IConfigurationSystem
{

public static void InstallForOpenNETCF()
{
Type configSettingsType = typeof (ONETConfig.ConfigurationSettings);

lock (configSettingsType)
{
// setting them again will cause an exception
Object existingConfig = configSettingsType.InvokeMember(
"configSystem",
(BindingFlags.Static |
BindingFlags.NonPublic |
BindingFlags.GetField),
null,
null,
null);

if (existingConfig == null)
{
configSettingsType.InvokeMember(
"SetConfigurationSystem",
(BindingFlags.Static |
BindingFlags.NonPublic |
BindingFlags.InvokeMethod),
null,
null,
new object[] {new PassThruConfigSystem()});
}
}
}

public PassThruConfigSystem()
{
}

public object GetConfig(string configKey)
{
return MSConfig.ConfigurationSettings.GetConfig(configKey);
}

public void Init()
{
}
}
}


In my next post I'll show you how to automatically install the PassThruConfigSystem when running unit tests with NUnit, which presents its own unique challenges!

Saturday, August 13, 2005

OpenNETCF 1.3 Reinstall Bug

OpenNETCF 1.3 has an annoying bug that causes it to be reinstalled by Visual Studio every time you run/debug an application. Here's a workaround to stop this from happening (OpenNETCF 1.4 also supposedly fixes the bug):

  1. Open this file: 'C:\Documents and Settings\[user profile]\Application Data\Microsoft\visualstudio\devices\7.1\conman_ds_package.xsl'. Make sure you open the right one as there may be copies under each user profile on your PC as well as under the 'All Users' profile.
  2. Save a backup copy.
  3. Find the following PACKAGE element: '<PACKAGE Name="OpenNETCF.dll" InvariantName="OpenNETCF.dll" ReadOnly="true" Protected="true" xmlns="">'
  4. Delete the entire PACKAGE element and all of its contents. (It's quite long--about 400 lines.) You may also need to restart Visual Studio if it's open.
This will stop the OpenNETCF automatic install/reinstall for all platforms, but you will need to manually install OpenNETCF the first time on any devices you are working with in the future.

 
Header photo courtesy of: http://www.flickr.com/photos/tmartin/ / CC BY-NC 2.0