Video Screencast Help

Creating DLL Custom Actions

Created: 22 Apr 2008 | 2 comments
Scot Curry's picture
0 0 Votes
Login to vote

In my role as a Sr. Systems Engineer specializing in Packaging and Software Virtualization, I often come across customers who would like to get access to a quick sample to get them started with a specific feature of Wise Package Studio and / or Windows Installer.

The Wise product and documentation team have done a great job of providing samples and help files, but there was one area where I was unable to send a customer a specific example. That area was the creation of a Windows Installer Custom Action that calls a DLL. To address this issue I have created the attached ZIP file that will hopefully get you on the right track.

Visual Studio 2005 Setup

The samples were created using Visual Studio 2005. The solution can be upgraded to Visual Studio 2008 if that is your current development environment. The initial setup is as simple as creating a New Project -> Visual C++ -> Win32 - (then selecting DLL when prompted by the wizard).

Function Definition

The IDE will set up appropriate DLL information:

BOOL APIENTRY DllMain( HMODULE hModule,
            DWORD ul_reason_for_call,
            LPVOID lpReserved )
{
  return TRUE;
}

You will then add the following line as defined in the Windows Installer SDK:

UINT __stdcall CustomAction(MSIHANDLE hInstall)
{
}

How To Use the Function

The key to this code is that Windows Installer passes a handle to the installation. You can then use this handle to pull properties out of the database. These properties can then be accessed by the custom action. The example code pulls the INSTALLDIR property out of the installation and writes it to a text file on your desktop.

The following code is used to pull the INSTALLDIR from the Windows Installer database.

LPTSTR propertyName = TEXT("INSTALLDIR");
retVal = MsiGetProperty (hModule, propertyName, TEXT(""), &bufsize);

Once you have created your function you will need to create an export definition file so the linker will make your functions available to call (in our case Windows Installer) applications. There is a .def file in the example code.

Debugging DLL Custom Actions

There are a couple of ways to debug DLL custom actions, but the one that is show in the source code is the use of a MessageBox call. When this MessageBox call is made, the installation stops. You can then attach Visual Studio to the msiexec process and use the usual IDE debugging techniques.

The version of the code that is currently compiled has the MessageBox lines commented out, so you would need to remove the comment lines if you want to use this technique.

Deferred Custom Actions

The example solution also has a DLL call in the deferred execution sequence. The user defined Windows Installer property that is available in the deferred sequence is a property called CustomActionData. The data that is passed to this property is set in the attached WSI in a Set Property action called SetDeferredProperty.

Conclusion

This example is only intended to provide partners and customers a quick way to get started writing Windows Installer DLL custom actions and is covered by the Altiris Juice Software License.

License: AJSL
By clicking the download link below, you agree to the terms and conditions in the Altiris Juice Software License
Support: User-contributed tools on the Juice are not supported by Altiris Technical Support. If you have questions about a tool, please communicate directly with the author by visiting their profile page and clicking the 'contact' tab.

Comments 2 CommentsJump to latest comment

R-Vijay's picture

A very informative post Acot !!

Cheers'
Vijay

Microsoft MVP [Setup-Deploy]
Weblog: www.msigeek.com

0
Login to vote
philbenson's picture

Just a heads up for those C/C++ developers who expect a dll to remain in memory until the dll is unloaded.

The CA dll's are loaded and unloaded automagically, so if you are expecting to for example, call a function from a dll, and then another, and expecting any variables etc. that (would have normally) been initialized and or set by the previous function call, then don't... ;-) It does not work that way, I found out the hard way long ago. CA dll calls are one shot only.

As for debugging, instead of using MessageBoxes, try this instead...

__asm {int 3};

This will cause the JIT debugger to start, and you can step through your dll code as normal...

Just my tuppence.

0
Login to vote