As an aside, as much as I appreciate the work Acresso did on Managed CA’s, DTF is a better direction to go.
1) It solves the problem of tatooing the msi process with a fixed version of the CLR
2) It’s linker ( MakeSfxCa ) is more flexible for including dependencies an
3) The interop is simply better
4) The hosting process has a better debugging story
5) It’s open source so it’s easier to see problems and get resolutions to issues
6) It’s not tied to one vendors authoring tools
In previous posts I’ve discussed the use of the InstallScript function CoCreateObjectDotNet()to include Managed Code in your InstallScript custom actions without any installation or registration of .NET assemblies. Still this had the downside of having to write InstallScript CA’s to act as a wrappers for your managed assembly. This increased the complexity of the solution and added slightly to the package size and execution latency.
In late 2006 I had an email discussion with Robert Dickau where I suggested the possibility of supporting managed code CA’s directly similar to the way InstallShield already has support for non Type1 DLL function exports via the “New Standard DLL” pattern. I also suggested that it would be good if they could support passing the MSI handle and providing a simple C# SDK that included a basic MSI interop.
While I’m not sure if I really inspired the next feature or if it’s just a case of great minds think alike ( except for certain great minds who seem hell bent on denying the fact that managed code is the future of windows development), InstallShield development has once again jumped in with some really cool stuff:
Support for Managed-Code Custom Actions
InstallShield lets you add managed-code custom actions to Basic MSI, InstallScript MSI, Merge Module, and Web projects. This type of custom action calls a public method in a .NET assembly that is written in managed code such as Visual Basic .NET or C#.
Ok, that doesn’t really give it justice. Let me show you a simple example. Let’s say you are writing a VSTO 3.0 Installer and you need a random number to write to the Office 2007 Count Registry Value. You could break out a C++ compiler and track down a standard library for generating a random number and build it as a MSI Type 1 DLL CA, but the odds are increasing every day that your team doesn’t have those obsolete skills anymore but instead is getting really good at writing managed code in C# or maybe VB.NET. Since you are deploying a VSTO installer you already have a dependency on the framework so why not just put the BCL to work for you?
Consider this simple code fragment:
Now let’s wire it up into InstallShield 2009:
Now here is where it gets a little cooler. With standard DLL’s you have to export them as stdcall and use Depends to confirm the function name. With CoCreateObjectDotNet() the assembly has to be attributed as ComVisible(true). However, with the new pattern you don’t need ComVisible and InstallShield uses reflection to help you complete the contract:
Now let’s assign the return code to a public property:
Finally, let’s schedule it in the sequences:
Finally, let’s just display it on the welcome dialog so we can see it works:
That’s pretty much all there is to it. You may have noticed that I scheduled the CA in both the Install UI and Install Execute sequences and set it to only execute once. This means I’ll have to add the public property to SecureCustomProperties if I expect the data to persist during UAC/Elevated/Managed full UI installs. Otherwise I’m ready to use this property in the Registry table as [RANDOMNUMBER].
If you are curious how it works, you’ll have to download the beta. Take a look at the CustomAction and ISClrWrap tables.
BTW there is also the possibility of using a “standard signature” which allows passing the MSI handle. There is rumors that Beta 2 will have an interop included so I’ll have to show how that pattern would work at a later date.