Thursday, February 7, 2008

Windows Installer Dll - Part 3

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

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

Once your custom action is ready to go, it is usually a good idea to debug it. The two best methods I’ve seen are:
  1. Stepping thought the code
  2. Writing to the log file

1. Step through the code

Visual Studio makes it easy, there is only a few steps to the process.

A) - Add a message box to the debug build of your DLL

Nothing new here...

UINT __stdcall MyFunction(MSIHANDLE hMsi)
{
#if _DEBUG
     AfxMessageBox(_T("MyFunction() -> Debug"));
#endif

     int x = 0;

     //complete custom tasks ...

     return ERROR_SUCCESS;
}

B) - Build your debug DLL and insert it into your .msi file

Use a program like orca to insert your debug DLL into the MSI file’s appropriate Binary table record.


Orca is a utility that will allow you to modify MSI packages. It comes with Microsoft’s Windows Installer SDK. If you have the SDK installed, Orac’s install can be found in the SDK’s bin folder. (usually – C:\Program Files\Microsoft SDKs\Windows\v6.0\Bin)

C) - Run the install and attach to process

When the install executes your custom action, the debug message box pops up. With the project open in Visual Studio, use the Debug Menu and select Attach to Process. Find the process who’s title matches the message box’s title, and Attach to it.

Debug->Attach to Process

D) - Set a breakpoint, dismiss the message box

Set a breakpoint in your code just after the message box. Once the message box is dismissed VS will break into the debugger. From here you will have full access to the usual debug windows, and tools.

 

2 - Writing to the log file

MsiProcessMessage() can be used to write data to the log file. It is always a good idea to write important information about your action to the log file. If the install fails, you only need to collect the log file to tell what is going on. The following code writes data to the log file.

UINT __stdcall MyFunction(MSIHANDLE hMsi)
{
#if _DEBUG
     AfxMessageBox(_T("MyFunction() -> Debug"));
#endif

     WriteToLog(hMsi, L"MyFunction - doing something...");

     return ERROR_SUCCESS;
}

void WriteToLog(MSIHANDLE hMsi, LPCTSTR szMsg)
{
     PMSIHANDLE hRec = MsiCreateRecord(1);
     MsiRecordSetString(hRec, 1, szMsg);
     MsiProcessMessage(hMSI, INSTALLMESSAGE_INFO, hRec);
}

 

There it is... This concludes the series on how to use C++ in a Windows Installer custom action. Of course, the code here hasn’t really done anything. The intent is to demonstrate how to hook up a DLL. Most, if not all, the samples given at this blog will be in C++ so this seemed like a logical place to start.

 

No comments: