Creating a cab installer for a Windows Mobile program is easy. After making a cab project you add your files and Visual Studio does everything else for you. But when you uninstall your application what happens to all of the registry entries and data files that your application has made? They get left behind unless you erase them yourself. Chances are your program won’t ever receive any notification that it is about to be uninstalled, so your program won’t be able to cleanup after itself. Instead you will need to create a DLL that contains custom actions. The installer build into the Windows Mobile device will call your DLL once before installation, once after installation, once before deinstallation, and right after deinstallation. So how to you make this custom DLL?
The custom DLL will be a Win32 DLL smart device project. The DLL must define four functions, Install_Init, Install_Exit, Uninstall_Init, and Uninstall_Exit. To cleanup after your program has been uninstalled you will place cleanup code in Uninstall_Exit Here is the code for the custom actions DLL that I wrote. I’ve added code to clean up the registry. If there are other programs that I’ve written still on the device they will be using the same registry hive to store their keys. If other programs are found the program will leave behing the \HKCU\Software\J2i.Net key as not to accidentally erase the keys that my other programs use. If there are no other programs found then J2i.Net will be removed.
BOOL APIENTRY DllMain(HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
void RemoveRegistryKeys();
///////////////////////////////////////////////////////////////
codeINSTALL_INIT Install_Init
(
HWND hWndParent,
BOOL fFirstCall,
BOOL fPreviouslyInstalled,
LPCSTR pszInstallDir
)
{
MessageBeep(0);
return codeINSTALL_INIT_CONTINUE;
}
///////////////////////////////////////////////////////////////
codeINSTALL_EXIT Install_Exit
(
HWND hWndParent,
LPCSTR pszInstallDir,
WORD cFailedDirs,
WORD cFailedRegKeys,
WORD cFailedRegVals,
WORD cFailedShortcuts
)
{
MessageBeep(0);
return codeINSTALL_EXIT_DONE;
}
///////////////////////////////////////////////////////////////
codeUNINSTALL_INIT Uninstall_Init
(
HWND hwndParent,
LPCSTR pszInstallDir
)
{
MessageBeep(0);
return codeUNINSTALL_INIT_CONTINUE;
}
///////////////////////////////////////////////////////////////
codeUNINSTALL_EXIT Uninstall_Exit
(
HWND hwndParent
)
{
RemoveRegistryKeys();
MessageBeep(0);
return codeUNINSTALL_EXIT_DONE;
}
void RemoveRegistryKeys()
{
HKEY hCompanyKey = NULL;
HKEY hSoftwareKey = NULL;
TCHAR buffer[MAX_PATH];
DWORD bufferSize = MAX_PATH;
bool canEraseCompanyKey = false;
//Delete the application key
RegOpenKeyEx(HKEY_CURRENT_USER, L"Software", 0, 0, &hSoftwareKey);
if (hSoftwareKey)
{
RegOpenKeyEx(hSoftwareKey, L"J2i.Net", 0, 0, &hCompanyKey);
if (hCompanyKey)
{
RegDeleteKey(hCompanyKey, L"MyColourPreferences");
canEraseCompanyKey = (ERROR_SUCCESS != RegEnumKeyEx(hCompanyKey, 0, buffer, &bufferSize, 0, 0, 0, 0));
RegCloseKey(hCompanyKey);
RegCloseKey(hCompanyKey);
if (canEraseCompanyKey)
RegDeleteKey(hSoftwareKey, L"J2i.Net");
}
if (hSoftwareKey)
RegCloseKey(hSoftwareKey);
}
}
To export the four functions the DLL will also need to contain a Module Definition file that exports the four functions. The contents of that file must look like the following.
| EXPORTS |
| Install_Init |
| Install_Exit |
| Uninstall_Init |
| Uninstall_Exit |
That’s all that needs to be in the DLL. When you create your installer you will need to add both the primary output of your program and this DLL to the project. The last thing that you need to do is change the CE Setup DLL setting on the CAB project. Select the CAB project from the Solutions Explorer and you will see the CE Setup DLL setting in the property editor. Click on the dropdown to the right of the setting and select Browse. Navigate to the native DLL that you created and your done. All you need to do is compile and build the CAB.
As an example there is a Visual Studio project attached to this entry. The project contains a program of trivial simplicity. All that you need to know about that program is that it will save the information you enter to the registry. Without the custom action when you uninstall this program that information would be left in the registry. But thanks to the custom action it will be removed.