I was complaining on Twitter about the long time it takes to compile a Compact Framework application and Steve Schoon informed me of a hack you can do to DRASTICALLY speed up the time it takes to compile! You can get the details here.

Read the entire thing so you are aware of what you’re disabling by performing this hack but unless you are constantly flipping back and forth to various different target platforms with your mobile development, you shouldn’t need this feature very often at all! It dropped our compile times down from about 3 minutes to about 10 seconds. It was amazing!

I am working on a project that contains nearly identical clients (same basic featuresets, different UI) in very different environments (Winforms, Mobile, and Web). The biggest difference is that the web sites (one client-equiv site, one admin site, and a set of web services) contains some additional functionality. I’ve architected this to maximize the amount of code we can reuse in all of these environments. The data tiers all implement common interfaces or abstract classes. The business tiers all extend classes in a shared DLL. And the presentation tiers are all independent but all go through the same basic API to call into the business tier. If I get interest in it, I can go more into this.

Because there is so much common functionality, the databases are all very similar (and in some cases, large parts are 100% identical). The winforms and web systems all use SQL Server for their databases (Express on the clients but we don’t hit any of those limitations). However, with our Compact Framework project, it’s quite a bit different since we have to use SQL Server Compact Edition (or whatever they’re calling it this month). We have yet to find an easy automated way to take a desktop database and convert it into a compact edition database, so we wrote a little utility. It only took a couple of days, so it wasn’t that bad. We essentially call the sp_tables proc in SQL Server in our development database, iterate through the results, and generate CREATE TABLE scripts based on it. Easy enough. And for the data, we simply use Command Builders and DataAdapters (we use a SqlCeCommandBuilders and SqlCeDataAdapter for the Compact Edition interface but it works just fine for us) and the WriteXml and ReadXml methods that go with it.

During development of our utility, we used the IgnoreSchema option with WriteXml when trying to fix a bug and forgot to turn it back off. This just came back to bite us in the ass! One of our tables in the final database that we’re converting is called “MessageType” and is a simple lookup table (2 ints and a varchar(50) is all). Well, when we were trying to import the data for it, we were getting an exception on the DataAdapter.Update call: “There was an error parsing the query.” We spent 2-3 hours trying to figure it out and we finally figured out the problem and it came back to that IgnoreSchema option that we had set and erroneously left!

So we have our “MessageType” table and we also had an “AuditLog” table. A column in the AuditLog table was called “MessageType” and was completely unrelated to our MessageType table. Yeah, bad naming here – we need to fix that obviously but it shouldn’t be enough to confuse .NET, right? Wrong! Since our XML files were generated without schemas, .NET must make some assumptions about the XML coming in. In this case, I think it decides that any XML node that comes up as <MessageType> is an entry for our MessageType table, when it comes time to populate our MessageType table. But when it goes into the XML we pass it, it sees the <MessageType> nodes from our AuditLog table and because the tag matches, it tries to start parsing it as though it belongs to our MessageType table, which will obviously fail! So now you see the source of our problem.

Switching IgnoreSchema back to WriteSchema was a simple fix to the problem. Other things can be done that could have resolved this specific problem but this was the most wrong thing we had done and needed to fix. Now, time to go play with a freshly generated set of SQL Server Compact Edition databases on our PDAs!

I was recently given the task to generate some API documentation for all of the code on a project I was working on (11 different projects, 3 different solutions) so I began looking into what was available. I remember using NDoc with old 1.1 projects, but that project was apparently abandanded. Microsoft has an October 2007 CTP release for a replacement called Sandcastle. It’s a suite of files that provide the core functionality of generating HTML and CHM files for documentation in an MSDN-like style. Apparently, this is what Microsoft uses internally to generate their MSDN documentation.

Unfortunately, Sandcastle comes with no GUI to use it but fortunately, there are several free GUIs written out there to do it for you. To find out more about it, I thought this site was most helpful.

I’m working on a project where we use Deployment Projects to deploy our public application. We’re still in beta phase so we don’t have a huge number of releases under our belt yet but so far things have been going pretty well (well, at least since we’ve gotten past the initial hurdles in getting our first installer out). Well, something new has jumped up and surprised us. And honestly, now that I understand it, I’m shocked that we’ve not seen it in any of our last 5ish releases.

So here’s the context: We had a prior version of our app installed and we wanted to upgrade from that version to the newest version. We have the installer uninstall the old version (for this part hopefully by now you know that it’s good and important for all assemblies in the installer to be properly versioned and at or above 1.0). This is done by the freebie stuff and the Uninstall events that get fired within our Installer Class/custom action to manage a few things, including our databases. Next the new version gets installed (again by the freebie stuff and custom actions). The last thing our custom action class does is upgrades our databases from the older verson to the newer version. This is how we’ve done things for the past 5ish versions and everything has worked just fine and dandy as long as we’re on the ball with versioning our assemblies correctly.

Well, this version I updated all of our installer files just as I had done with the previous versions and when I went to test it, I was surprised. For some reason the install seemed to work fine EXCEPT for our custom actions. To make a long story short, what was happening was that our custom actions from our previous version were getting executed when the installer was installing the newer version!! So obviously since our databases are maintained by these custom actions, the problems were pretty obvious from the beginning.

I ultimately found this article online which points to this KB article of Microsoft’s (EDIT:this is the VS2005 version of the bug, I previously linked the VS2003 version of the bug) and it turns out that this is a bug in Visual Studio 2005 that was posted in August of 2004. The short version of the problem is with the assembly name for our custom action. When Windows Installer loads CustomAction v3 for the uninstall and attempts to load CustomAction v4 for the new install, it unreliably does not load v4 because it sees it already has CustomAction loaded but forgets to care about what version it is. So then when the new version of the app fires the events for our DLL, they get handled by the old code and not by the new code.

There are two things to be aware of with this scenario to fix it. The first is an end-user work-around in case you need such a thing for an installation that you might have already made public. If the end-user runs your installer and this happens, running the installer again and selecting “Repair” will then run the correct version of the DLLs. Now this may or may not help you, depending on your scenario. Luckily for us, this is an acceptable work-around without trashing any data because of our architecture around updating our client databases with each release. Now the second thing to be aware of is a more permanent fix. If you change the Assembly name for your custom action to be unique with each deployment, this will allow you to prevent this from happening again. So instead of my custom action’s assembly name being “Company.Project.Installer.CustomAction” it is now “Company.Project.Installer.CustomAction_v1.0.0.3″ and of course I change this with each release.

Good luck and I hope you find this problem and solution before wasting hours of time like I did!