Custom Setup DLL

A custom SetupDLL allows the developer to perform custom actions before and after the installation and uninstallation of a CAB package on a target device. A Windows Mobile/CE Setup DLL must export the following 4 predefined functions (using a DEF file):

  • “Install_Init” - called just before the CAB package is installed on the target device. Can be used to check the version of the application during reinstallation and determine if a dependent application exists.
  • “Install_Exit” - called once the installation is complete. Can be used to handle errors that occur during installation.
  • “Uninstall_Init” - called just before the application is uninstalled. Can be used to close a running application before removal begins.
  • “Uninstall_Exit” - called after the application has been uninstalled.

The header file "ce_setup.h" must be included in "stdafx.h" or alternatively in the main CPP source file of the DLL. You can use the following code both as a sample as well as a starting point for your own Setup DLL:

#include "stdafx.h"
#include <ce_setup.h>

const TCHAR szTitle[]       = _T("CESetup DLL");
const TCHAR szInst_Init[]   = _T("Install_Init\n\nContinue?");
const TCHAR szInst_Exit[]   = _T("Install_Exit\n\nContinue?");
const TCHAR szUninst_Init[] = _T("Uninstall_Init\n\nContinue?");
const TCHAR szUninst_Exit[] = _T("Uninstall_Exit");

/**
 * Install_Init
 */
codeINSTALL_INIT Install_Init(HWND    hwndParent,
                              BOOL    fFirstCall, // is this the first time this function is being called?
                              BOOL    fPreviouslyInstalled,
                              LPCTSTR pszInstallDir)
{
  // TODO: Add custom installation code here

  // To continue installation, return codeINSTALL_INIT_CONTINUE
  // If you want to cancel installation, return codeINSTALL_INIT_CANCEL

  if (IDOK == MessageBox(hwndParent, szInst_Init, szTitle, MB_OKCANCEL))
    return codeINSTALL_INIT_CONTINUE;
  else
    return codeINSTALL_INIT_CANCEL;
}

/**
 * Install_Exit
 */
codeINSTALL_EXIT Install_Exit(HWND    hwndParent,
                              LPCTSTR pszInstallDir,  // final install directory
                              WORD    cFailedDirs,
                              WORD    cFailedFiles,
                              WORD    cFailedRegKeys,
                              WORD    cFailedRegVals,
                              WORD    cFailedShortcuts)
{
  // TODO: Add custom installation code here

  // To exit the installation DLL normally, return codeINSTALL_EXIT_DONE
  // To unistall the application after the function exits, return codeINSTALL_EXIT_UNINSTALL

  if (IDOK == MessageBox(hwndParent, szInst_Exit, szTitle, MB_OKCANCEL))
    return codeINSTALL_EXIT_DONE;
  else
    return codeINSTALL_EXIT_UNINSTALL;
}

/**
 * Uninstall_Init
 */
codeUNINSTALL_INIT Uninstall_Init(HWND hwndParent, LPCTSTR pszInstallDir)
{
  // TODO: Add custom uninstallation code here

  // To continue uninstallation, return codeUNINSTALL_INIT_CONTINUE
  // If you want to cancel installation, return codeUNINSTALL_INIT_CANCEL

  if (IDOK == MessageBox(hwndParent, szUninst_Init, szTitle, MB_OKCANCEL))
    return codeUNINSTALL_INIT_CONTINUE;
  else
    return codeUNINSTALL_INIT_CANCEL;
}

/**
 * Uninstall_Exit
 */
codeUNINSTALL_EXIT Uninstall_Exit(HWND hwndParent)
{
  // TODO: Add custom uninstallation code here

  MessageBox(hwndParent, szUninst_Exit, szTitle, MB_OK);
  return codeUNINSTALL_EXIT_DONE;
}

Some additional notes:

  • The DLL must be compiled using either eMbedded Visual C++ 3.0 (eVC 3.0), eMbedded Visual C++ 4.0 (eVC 4.0), Visual C++ 2005 or Visual C++ 2008 (Professional version required). If you are targeting only Pocket PC 2003, SmartPhone 2003 or later devices, eVC 4.0, VC 2005 or VC 2008 can be used (eVC 4 is free); for earlier devices, eVC 3.0 will be used (also free). See the Development tools support matrix for more details.
  • If you are targeting multiple devices with different processors, you must compile the DLL for each supported processor type.
  • Consequently, you need to create a separate CAB file (define a new configuration) for each supported CPU type.