Click here to Skip to main content
Click here to Skip to main content

Creating Pocket PC Application Setup Packages Using the CAB Wizard - 2

, 14 Jul 2004
Rate this:
Please Sign up or sign in to vote.
An article describing the implementing of Custom actions in Pocket PC application Setup packages.

Introduction

In my previous article Creating Pocket PC Application Setup Packages with Cabwizard 1 we saw how to use Cabwizard utility to create application setup files. While the installation / uninstallation of application is in progress we might need to do custom actions like delete some files, add a new entry to today screen etc. These actions cannot be specified in the application cab files generated as they are executed when the installation / uninstallation of application is taking place. In these cases we can write a DLL, integrate it with cab files generated. The DLL will be invoked during installation and uninstallation of the application. This article discusses how to create this DLL and integrate it with the application cab files.

At the end of this article you will know

  • What is the need for implementing Custom actions in cab files?
  • How to integrate custom actions with cab file?

Prerequisites

Tools needed:

What is a custom action?

A Custom action is a piece of code executed during the installation / uninstallation process of a application.

What is the need for Custom actions during application installation / uninstallation process?

  • Cleanup of files created by Pocket PC application
  • Installing external or runtime libraries like .NET Compact Framework required for proper functioning of Pocket PC application
  • Executing external applications

Example Case study:

Assume there is a pocket pc application which gives options to add / modify / delete / view data from database. The database is getting created when you first start the application. You start the application, populate data, manipulate it and view the data. But when you uninstall the application from the device, the application doesn't uninstall properly. You get a message telling that some files were not removed.

Why? Because of the database file the application created when it was first started. Whatever files which are copied or created when the application installs to the device will get automatically deleted (except when they are shared files like COM objects) when the application is uninstalled from device. But the files or databases or things like log files which are created after the application gets installed or during runtime doesn't get deleted. In this scenario we can use custom actions to accomplish these cleanup tasks.

When can we execute Custom actions?

  • Before installation process starts
  • After installation process ends
  • Before Uninstallation process starts
  • After Uninstallation process ends

So basically in VB terms, we will be writing event handlers for these events and attaching the code to cab files.

Who executes the custom actions?

These event handlers will be called during the installation / uninstallation process by WCELOAD.exe which executes the .cab files These event handlers can be written only in a WIN32 or MFC DLL and integrated with the cab files. Please note that this cannot be implemented using .NET CF. There are four event handlers or functions which need to be exported from DLL

  • Install_Init
  • Install_Exit
  • Uninstall_Init
  • Uninstall_Exit

As the names suggest,Install_Init() gets called before installation process starts. Install_Exit() gets called after installation process gets over. Uninstall_Init() gets called before uninstalltion process starts and Uninstall_Exit() gets called after the Uninstallation process gets over.

How to implement custom actions with cab file:

We will see how to implement custom actions with cab files through a example. The following are the sub steps which need to be implemented for the example.

  • Creating a simple EVB application
  • Generating the setup package of EVB application using Application Setup wizard
  • Creating a WIN32 DLL containing the custom code to be called during installation and uninstallation
  • Integrating the DLL with the cab files generated.

Creating EVB application

  • Open EVB and create a new Pocket PC 2002 project named TestApp
  • Set the ShowOK property of Form to true
  • Include SQL CE, ADOCE 3.1, ADOXCE libraries by selecting Project => References.
  • Add a Command Button to the form, set name property of Command Button to 'cmdcreate'
  • In the click event of button include the following code

    Private Sub cmdcreate_Click()
        On Error Resume Next
        'local variables
        Dim objcatalog As ADOXCE.Catalog
        Dim strconn As String
    
        'create catalog object
        Set objcatalog = CreateObject("ADOXCE.Catalog.3.1")
    
        'set connection string
        strconn = "Provider=Microsoft.SQLSERVER.OLEDB.CE.2.0; data source=" 
               & App.Path & "\test.sdf"
        'MsgBox strconn
    
        'create database
        objcatalog.Create strconn
    
        'check for errors
        If Err.Number <> 0 Then
        MsgBox Err.Number & " : " & Err.Description, , "error"
        Else
        MsgBox "database created"
        End If
    
        'destory catalog object
        Set objcatalog = Nothing
    End Sub
                        
  • Select File = > Make TestApp.vb. Now the EVB application is ready.

Generating the setup package of EVB application using Application Setup wizard

  • Select Tools => Remote Tools => Application Install Wizard
  • Follow the steps in the wizard

Creating a WIN32 DLL containing the custom code to be called during installation and uninstallation

  • Start EVC++ and create a empty WCE Dynamic Link library project named 'setupdll'
  • Add a header file 'ce_setup.h" to the project. This header file contains the declarations of the 4 functions mentioned above and is normally located in \Windows CE Tools\wce300\Pocket PC 2002\include subdirectory of path where you have installed the Pocket PC SDKs. Copy the file to your project directory and include it in the project workspace by selecting Project => Add to Project => Files and selecting the file.
  • To add source files select File => New => C++ source file. give the name as 'setupdll' in the Filename field and click ok button. A new file named 'setupdll.cpp' will be created and included in the project workspace.
  • Include the following code in the .cpp file

    #include <windows.h> 
    #include "ce_setup.h"
    
    ///////////////////////////////////////////////////////////
    //PURPOSE : HANDLES TASKS DONE AT START OF INSTALLATION
    ///////////////////////////////////////////////////////////
    codeINSTALL_INIT Install_Init(HWND hwndparent,
      BOOL ffirstcall,BOOL fpreviouslyinstalled,LPCTSTR pszinstalldir)
    {
        //do nothing
        //return value
        return codeINSTALL_INIT_CONTINUE;
    }
    
    ///////////////////////////////////////////////////////////
    //PURPOSE : HANDLES TASKS DONE AT END OF INSTALLATION
    ///////////////////////////////////////////////////////////
    codeINSTALL_EXIT Install_Exit(
        HWND hwndparent,LPCTSTR pszinstalldir,
        WORD cfaileddirs,WORD cfailedfiles,WORD cfailedregkeys,
        WORD cfailedregvals,
        WORD cfailedshortcuts)
    {
        //do nothing
        //return value
        return codeINSTALL_EXIT_DONE;
    }
    
    ///////////////////////////////////////////////////////////////
    //PURPOSE : HANDLES TASKS DONE AT BEGINNING OF UNINSTALLATION
    ///////////////////////////////////////////////////////////////
    codeUNINSTALL_INIT Uninstall_Init(
      HWND hwndparent,LPCTSTR pszinstalldir)
    {
        //local variables    
        WIN32_FIND_DATA findfiledata;
        HANDLE hfind;
        TCHAR pszfilepath[50];
    
        //initialize character array
        memset(pszfilepath,0,sizeof(pszfilepath));
    
    
        //copy database path to character array
        //pszinstalldir variable will contain the 
        //application path (eg : \Program Files\TestApp)
        wcscpy(pszfilepath,pszinstalldir);
        wcscat(pszfilepath,TEXT("\\test.sdf"));
    
        //trying to find whether database file exists or not
        hfind = FindFirstFile(pszfilepath,&findfiledata);
    
        if(hfind != INVALID_HANDLE_VALUE) //database file exists
        {
            //delete database
            DeleteFile(pszfilepath);
        }
    
        //return value
        return codeUNINSTALL_INIT_CONTINUE;
    }
    
    
    ///////////////////////////////////////////////////////////
    //PURPOSE : HANDLES TASKS DONE AT END OF UNINSTALLATION
    ///////////////////////////////////////////////////////////
    codeUNINSTALL_EXIT Uninstall_Exit(HWND hwndparent)
    {
        //do nothing
        //return value
        return codeUNINSTALL_EXIT_DONE;
    }
    
                    
  • Now we have added the code for the DLL. Inside Uninstall_Init() which gets called when uninstallation process starts we are checking for the existence of the database file and if it exists we are deleting it. the DLL.
  • To make the functions accessible from external applications we need to make them public. This process is called 'exporting'. For that create a .def file by selecting File = > New = >Text File. Give the name as setupdll.def and press ok. The .def file contains the functions or symbols exported by the DLL. Include the following lines in the file.

    EXPORTS
        Install_Init
        Install_Exit
        Uninstall_Init
        Uninstall_Exit
                        
  • Compile the DLL for ARM and X86 platforms by selecting Build => Build setupdll.dll. Set the respective platforms for which DLL is compiled by selecting Build = > Set Active Configuration.

Integrating the DLL with the cab files generated:

We now have to integrate the DLL with the setup package. The Cabwizard generates the setup package by reading the .inf file. We will edit the .inf file, include the path of the setup dll in the .inf file and again invoke Cabwizard utility with this .inf file as argument to generate setup packages. Here are the steps to follow for integrating the setup dll with cab files

  • Navigate to directory where setup files are generated. If the setup package has generated correctly the directory will have following sub directories App, Arm 1100 (4K) v3.00, I486 (4K) v3.00, CD1 and following files Readme.txt, TestApp.inf
  • Copy the DLL files compiled for ARM and X86 platforms to Arm 1100 (4K) v3.00 and I486 (4K) v3.00 directories respectively.
  • Open the TestApp.inf file and remove the following sections [CEDevice.I486 (4K) v3.00] and [CEDevice.Arm 1100 (4K) v3.00] from the .inf file. If these sections are present, the cab files will not get executed in Pocket PC emulator.
  • Navigate to [DefaultInstall] section and insert the key/value CESETUPDLL="setupdll.dll" before other keys. By this entry we are specifying to execute custom actions from setupdll.dll
  • Now we have to give path details of DLL. For that add a entry setupdll.dll=3 at end of [SourceDisksFiles.I486 (4K) v3.00] and [SourceDisksFiles.Arm 1100 (4K) v3.00] sections.
  • Add a entry setupdll.dll,,0x80000000 at end of [Files.I486 (4K) v3.00] and [Files.Arm 1100 (4K) v3.00] sections

For more details regarding .inf file please refer to my previous article

Thats all. .inf file is ready. Now we have to invoke Cabwizard utility with the .inf file as argument. For that open the Readme.txt file. As given in the file copy the command line text in command prompt and execute it. If everything goes well the cab files should be generated in the directory where the setup files are created by Application Install Wizard utility. Copy the cab files to CD1 folder.

Testing the .cab files

Now to see whether the setup dll is being called. In case of testing in the Pocket PC device just execute the setup.exe file in CD1 directory and cab files generated for ARM platform are automatically copied to device and executed. . In case of Pocket PC emulator copy the cab file generated for X86 platform and execute the file. The application gets installed. Invoke the EVB application. create the SQL Server CE database by clicking on the 'create' command button and close the application. Now select Start Menu => Settings => System => Remove Programs and click on TestApp application and click the Remove button. The application gets removed cleanly. Our Custom action code executes before uninstallation process deleting the database file.

Conclusion

So we saw how custom actions can be integrated with .cab files making our application install package even more powerful and feature oriented. Hopefully in my next article we will see how to integrate custom COM DLLS into cab files. Please give your valuable suggestions on this article.

References

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Girish Nurani Sankaranarayanan
Web Developer
India India
No Biography provided

Comments and Discussions

 
Questionreg Custom CAB creation Pinmembervenuchary19-Apr-12 1:09 
QuestionReg CAB File . Pinmembervenuchary12-Apr-12 2:34 
QuestionAdding uninstallation to my CAB app with a dependency Pinmembersatishkumarbarla9-Jan-12 21:14 
QuestionHow to include a dialog in the setupdll? PinmemberFlyingDancer26-Dec-05 16:03 
QuestionHow to link setup to dll? PinmemberRavikiran__D6-Dec-05 2:57 
GeneralUninstall_Init problem Pinmemberram_by22-May-05 1:38 
Generalneed help with setupdll and uninstall PinmemberSandhyaPillai6-Mar-05 18:06 
QuestionHow to restart? Pinmembercbusgut30-Nov-04 5:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 15 Jul 2004
Article Copyright 2004 by Girish Nurani Sankaranarayanan
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid