Monday, February 4, 2008

Windows Installer Dll - Part 2

Audience: Install Developers, Beginner, Windows Installer (MSI) Knowledge

This is Part 2 of a three part series that demonstrates how to use C++ in a Windows Installer Custom Action.

Once your function is written and the DLL is created, you need to call it through a custom action. There are 2 ways to call a Windows Installer DLL.
  1. Custom Action Type 1 (store the DLL in the MSI file’s Binary table)
  2. Custom Action Type 17 (install the DLL with the product)

Hooking up the DLL in your setup project is easy. No matter what install authoring software you are using (InstallShield, Vise, Wise, Advanced Installer) – there will be some sort of wizard that guides you through the process.

I don’t think there is any value in me putting up screen shots, or demonstrating how these wizards work. Instead, lets look at some tips that will help you produce easy to maintain and 'readable' setup projects.


1 - Use Comments

This one gets missed a lot. Especially, when there is only one install developer that works on the project.

Some authoring software (InstallShield) has a comment field for the custom actions. I have found it is nice to see the comment used to tell why the custom action is needed. The function definition in you DLL’s source code should also have a quick description that describes the purpose of the function. Nothing to fancy, just enough that people can tell what’s going on.

// Example:
// checks to see if [INSTALLDIR] is too long
UINT __stdcall CA_EvaluateInstallPath(MSIHANDLE hMsi)
{
     /* ... code does something ... */

     return ERROR_SUCCESS;
}



2 - Use a Naming Convention for your Custom Actions

A) Use appropriate names for your custom actions and functions. -- You and other developers may need to maintain the code at a later date, your names should typically reflect something about what the custom action is responsible for.

Matching your Action name (custom action name) with the Target (exported function in the DLL) can be a big help if there are many functions in the same DLL.

B) Explicitly name important the Binary table entries. -- Most install authoring software will just pick a name like ‘NewBinary0' – if you take the time to rename it to something that reflects the actual source then your project will be easier to maintain thought it’s life cycle. There is no need to rename them all, just the ones that you many want to keep track off. The point here is it is better to see something like My.dll in the binary table, instead of NewBinary88.




3 - Custom Action Type 1 is easier than Custom Action Type 17

If you can get away with it, always choose Type 1 (DLL stored in the binary table) over, Type 17. It is just easier. You can use Type 1, and call the custom action anytime during the setup.

However, Type 17 can only be executed after InstallFiles and you need to use a condition on your action so that it will only run if the component has been installed.


4 - Any Action that Modifies the System Needs to be Deferred in System Context

If your action needs to modify the system, then it should be executed in the system context. This will ensure that the action will have the required permissions on the computer.

Secondly, if your action modifies the system, consider writing a rollback action as well. If the install fails after the system modification has been preformed, then the change should be undone when the install rolls back.



That’s it. The above tips will help ensure your setup project readable, easy to maintain and hopefully prevent a bug or two.

Next will move on to some debugging techniques for C++ custom actions.




No comments: