Rob mentioned in this morning’s announcement that I’ve been working on the DTF project for quite a while. Indeed, if you look at the change history topic in DTF.chm, you’ll see entries going back to January 2003. (And development of what would become DTF actually started over a year prior, when .NET 1.0 was not quite released yet.) Before I get into some technical topics, I wanted to talk about how the project evolved, and maybe explain a bit about why it took so long to get released externally.
As I said in my introduction, in previous years I spent a lot of time working on internal deployment-related tools. Specifically these were tools for authoring, building, installing, testing and debugging MSIs and MSPs for DevDiv products, mostly Visual Studio and .NET Framework. I found very early that programming against the Windows Installer APIs in C++ is a slow and sometimes arduous task, and while script is easier to write it’s not a robust scalable solution. I wanted to take advantage of the great productivity gains of the then-new .NET platform, so I started by creating a limited interop library for accessing the MSI APIs from a .NET language. As I worked on more tools, I gradually filled out and improved that interop library. I also added a cabinet library since working with MSI setups often involves dealing with cabinets.
After sharing it with a few other teams in the company who were also working on deployment related tools, I got great feedback on the value of the project, which motivated me to cover the remaining MSI APIs and add more documentation to make it a more complete framework. Most of this work was actually done outside of my day job — I would work a few evenings and weekends on the project now and then, just motivated by the positive feedback and knowing that I was making other developers’ jobs easier.
The debate about managed custom actions is nearly as old as managed code. While the .NET Framework has always provided an InstallUtil tool that lets you invoke managed assembly Installer classes during the setup, it is, to be blunt, a managed version of self-reg suffering from nearly all the problems that plague classic DLL self-registration. That means InstallUtil custom actions usually are not a good idea if you’re interested in creating a really clean and robust setup. Still, if you’re working with a product or platform that’s all based on managed code, it’s likely your setup will need to run managed code to intract with it.
So with the DTF project I took on the challenge of enabling real managed custom actions that have all the capabilities of unmanaged custom actions in terms of access to the installer session, allowing them to follow the best practices for data-driven custom actions. Given that I already had a library that exposed all the MSI APIs in managed code, I was halfway there, or so I thought. Over the years I went through three major design iterations for how the managed-code CA got launched. While the earlier designs seemed to work well, they suffered from some subtle robustness issues related to interactions between the CLR and the MSI engine. It wasn’t until last summer that I finally overcame the last technical hurdle (described in Rob’s blog post) to achieve what I believe now is a robust framework for managed custom actions.
For several years I’ve been looking for a way to release the DTF project externally, since I think there are lots of developers who would find it useful. There have been a number of reasons why it didn’t happen until now. For a while the MSI team was hinting that they might implement their own set of official managed APIs for the Windows Installer platform (and I didn’t want to cause confusion with an alternative), but now it doesn’t look like that will happen anytime soon if ever. Also I didn’t want to release a framework for managed custom actions until I had something that addressed robustness issues with CLR and MSI interactions.
The final barrier to releasing DTF was the strategic concern, also described by Rob, about wanting to reduce people’s reliance on custom actions in their setups. Personally on this issue I’ve always been somewhat of a pragmatist: the MSI platform can never support everything that people might possibly need to do in their setups, so there will always be a need for some custom actions. And if my framework can make it easier for those people to write quality custom actions, I think that’s a good thing. Now that a few other key people here have more or less come around to that point of view, DTF could finally be released. I hope all the developers out there will prove us right by not writing too many crazy ill-conceived managed custom actions.