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

Automatically Install Multiple CAB Files to a Windows Mobile/Pocket PC Device

, 13 Mar 2010 CPOL
Rate this:
Please Sign up or sign in to vote.
A solution that uses threading and ActiveSync to automate the process of installing multiple CAB files to a Windows Mobile or Pocket PC device

Introduction

The objective of this article is to describe a solution that uses threading and ActiveSync to automate the process of installing multiple CAB files to a Windows Mobile or Pocket PC device. 

The included example setup project is a standard Windows MSI installation file which when run will install two CAB files to a Windows Mobile or Pocket PC device.

The Custom Action included in the project is responsible for the installation of the CAB files to the device, and it installs each of the CAB files, one at a time, consecutively using ActiveSync. Each installation is run in a separate thread, and the main process waits until each installation has completed before proceeding with the next installation.

For the purposes of this example, I have included two CAB files, but the Custom Action can easily be extended to install as many CAB files as you wish. The included CAB files will install the .NET Compact Framework 3.5 and SQL Mobile 2.0.

Description

The Custom Action works by overriding and extending the default functionality of the Installer class. The overridden Commit method of the installer class first calls the base Commit method and then proceeds to implement the custom functionality.

Broadly, the custom functionality works as below:

  1. All the CAB files are copied by the installer to the initial installation target directory. The MSI does this automatically.
  2. The Custom Action then initializes an InstallParams object which takes an AutoResetEvent object (used to signal when the thread has terminated) and a string which identifies the initialization (.ini) file of the CAB to be installed.
  3. The method RunInstallerTask and the InstallParams object are used to fire up a new  thread through a call to ThreadPool.QueueUserWorkItem.
  4. The new thread fires up a process, i.e., executes a program, in this case ActiveSync. If ActiveSync is installed, the default installation directory of ActiveSync is retrieved from the Registry key: HKEY_LOCAL_MACHINE\Software\microsoft\windows\currentversion\app paths\ceappmgr.exe.
  5. While ActiveSync executes and installs the target CAB, the new (executing) thread waits, intermittently checking the Process.HasExited property (of the Process class) every 1000 milliseconds. When the process has exited, it signals the AutoResetEvent through a call to the Set() method of the AutoResetEvent object. This signals the calling thread, which had been in an efficient wait state (through a call to the AutoResetEvents WaitOne method), to continue executing.
  6. The process from step II. is repeated for any subsequent CAB file that will be installed.

Implementation

InstallParams class

The InstallParams class is fairly easy to understand. As mentioned before, it simply contains an AutoResetEvent object and a string containing the CAB file installation initialization file (.ini). An InstallParams object is passed as the second parameter to ThreadPool.QueueUserWorkItem.

This class is implemented as a nested public class, as part of the CABFileInstaller class.

CABFileInstaller class

This class is derived from the Installer class (declared as partial, and therefore a derived extension of the standard library base Installer class). The only overridden method of the Installer class is the Commit method, which calls the base Commit method before implementing any custom functionality.

The class has a private string member (string appPath) which stores the path to the ActiveSync executable.

This derived class also has an additional private method called RunInstallerTask which starts ActiveSync and installs the CAB file based on the information in the .ini file (described below). This method depends on information passed to the setup process as part of its context in order to determine the path to the target directory.

The line strIniFilePath = "\"" + Context.Parameters["targetdir"]... in the RunInstallerTask method determines the target installation directory from the current context. In order to implement this, the CustomActionData property of the Custom Action must be set to /targetdir="[TARGETDIR]\", as described in the walkthrough below.

The initialization file (.ini)

For each CAB file that is to be installed, an .ini file in the given format must be created and installed to the MSI target directory. The MSI does the transfer to the installation folder automatically, but you must create the ini file for each CAB and add it to the files included in the ApplicationFolder of the setup project.

The details of the contents of the .ini file and its format are available on MSDN at this URL: http://msdn.microsoft.com/en-us/library/bb158614.aspx.

For a simple example of an .ini file, the one used to install the .NET Compact Framework CAB file (NETCFv35.ini, in the included example) looks like this:

[CEAppManager]
Version      = 1.0
Component    = NETCFv35.ppc.armv4
[NETCFv35.ppc.armv4]
Description  = RMS Stock Count Client
CabFiles     = NETCFv35.ppc.armv4.cab

The first two lines never change, i.e., [CEAppManager], and the version must always be 1.0.

The Component value must match the beginning of the next section, and the last (CabFiles) value should match the exact name of the CAB file(s) being installed. One may include more than one CAB file on the last line separated by commas to support different architectures. In this case, the .NET Compact Framework CAB file included is for ARM type processors.

Project setup - Walkthrough

I used Visual Studio 2008, but this should work for VS2005 as well.

To create the custom action

  1. On the File menu, click New Project.
  2. In the New Project dialog box, select Visual C# Projects in the Project Types pane, and then click Class Library in the Templates pane. In the Name box, type CABInstallCustomAction.

    The project is added to Solution Explorer.

  3. On the Project menu, click Add Class, and then in the Add New Item dialog box, select Installer Class. Type in the name as CABFileInstaller.cs. Click Add.
  4. Switch to code view by clicking Click here to switch to code view on the design surface (or by right-clicking the design surface and clicking View Code).
  5. In the Code Editor, add the following code to CABFileInstaller.cs, after the class declaration (also see the same file accompanying this article in the example solution):

    To declare the InstallParams class:

    public class InstallParams
    {
        private AutoResetEvent reset;
        private string strIniFile;
    
        public InstallParams(AutoResetEvent ev, string ini_file)
        {
            if (ev == null)
                throw new Exception("Null reset event");
            reset = ev;
            strIniFile = ini_file;
        }
    
        public AutoResetEvent Reset
        {
            get
            {
                return reset;
            }
        }
    
        public string IniFile
        {
            get
            {
                return strIniFile;
            }
        }
    }

    To declare the private string app path:

    private string appPath = null;

    To create the RunInstallTask method:

    private void RunInstallerTask(Object iparam)
    {
        int time = 0;
        InstallParams iparams = iparam as InstallParams;
        AutoResetEvent are = (AutoResetEvent)iparams.Reset;
        // Get the target directory where the .ini file is installed.
        // This is sent from the Setup application
        string strIniFilePath = "\"" + Context.Parameters["targetdir"] + 
                                iparams.IniFile + "\"";
        // Now launch the Application Manager - ActiveSync
        System.Diagnostics.Process process = new System.Diagnostics.Process();
        process.StartInfo.FileName = appPath;
        process.StartInfo.Arguments = strIniFilePath;
        process.Start();
        while (!process.HasExited)
        {
            time = 1000;
            Thread.Sleep(time);
        }                
        are.Set();
    }

    To create the overridden Commit method:

    public override void Commit(System.Collections.IDictionary savedState)
    {
        // Call the Commit method of the base class
        base.Commit(savedState);
    
        AutoResetEvent ev;
        InstallParams ip;
        Microsoft.Win32.RegistryKey key = null;
    
        // Open the registry key containing the path to the Application Manager
        key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(
               "Software\\microsoft\\windows\\currentversion\\app paths\\ceappmgr.exe");
    
        // If the key is not null, then ActiveSync
        // is installed on the user's desktop computer
        if (key != null)
        {
            // Get the path to the Application Manager from the registry value
            appPath = key.GetValue(null).ToString();
    
            if (appPath != null)
            {
                //.Net 3.5
                ev = new AutoResetEvent(false);
                ip = new InstallParams(ev, "NETCFv35.ini");
                ThreadPool.QueueUserWorkItem(new WaitCallback(RunInstallerTask), ip);
                ev.WaitOne();
                //SQL
                ev = new AutoResetEvent(false);
                ip = new InstallParams(ev, "sql.ini");
                ThreadPool.QueueUserWorkItem(new WaitCallback(RunInstallerTask), ip);
                ev.WaitOne();                    
            }
        }
        else
        {
            // No Active Sync - throw an error message
            throw new Exception("ActiveSync Not Installed");
        }
    }
  6. In Solution Explorer, right-click Class1.cs and then click Delete (because it is unnecessary).

To add a deployment project

  1. On the File menu, point to Add, and then click New Project.
  2. In the Add New Project dialog box's Project Type pane, open the Other Project Types node, and then select Setup and Deployment Projects. In the Templates pane, click Setup Project. In the Name box, type MultipleCABFilesSetup.

    The project is added to Solution Explorer and the File System Editor is displayed. Copy the CAB files and the corresponding .ini files to the project folder.

  3. In the File System Editor, select Application Folder in the left pane. On the Action menu, point to Add, and then click File. Add all the CAB files and corresponding .ini files to the application folder in this way.
  4. In the File System Editor, select Application Folder in the left pane. On the Action menu, point to Add and then click Project Output.
  5. In the Add Project Output Group dialog box, CABInstallCustomAction will be displayed in the Project list. Select Primary Output.

    Primary Output from CABINstallCustomAction (Active) appears in the Application Folder.

To add the custom action

  1. Select the MultipleCABFilesSetup project in Solution Explorer. On the View menu, point to Editor, and then click Custom Actions.

    The Custom Actions Editor is displayed.

  2. In the Custom Actions Editor, select the Install node. On the Action menu, click Add Custom Action.

  3. In the Select Item in Project dialog box, double-click the Application Folder. Select Primary output from CABInstallCustomAction.

    Primary output from CABInstallCustomCation appears under the Install node in the Custom Actions Editor.

    In the properties window, add the following line to the CustomActionData property: /targetdir="[TARGETDIR]\". This data is passed to the Custom Action in order to locate the ini and CAB files in the target installation directory. See the custom action code.

  4. In the Properties window, make sure that the InstallerClass property is set to True (this is the default).
  5. In the Custom Actions Editor, select the Commit node. On the Action menu, click Add Custom Action.
  6. In the Select Item in Project dialog box, double-click the Application Folder. Select Primary output from CABInstallCustomAction.

    Primary output from CABInstallCustomCation appears under the Commit node in the Custom Actions Editor.

    In the properties window, add the following line to the CustomActionData property: /targetdir="[TARGETDIR]\". This data is passed to the Custom Action in order to locate the ini and CAB files in the target installation directory. See the custom action code.

  7. In the Properties window, make sure that the InstallerClass property is set to True (this is the default).

  8. On the Build menu, click Build Custom Action Installer.

To install on your development computer

  • Make sure the target device is connected and a partnership has been setup using ActiveSync. Then, select the MultipleCABFilesSetup project in Solution Explorer. On the Project menu, click Install.

This will run the installer and install MultipleCABFilesSetup on your development computer. At the end of installation, you should see ActiveSync start and prompt you to install the .NET Compact Framework followed by the SQL Client .

You must have install permissions on the computer in order to run the installer.

To deploy to another computer

  1. In Windows Explorer, navigate to your project directory and find the installer. The default path will be \Documents and Settings\<yourloginname>\My Documents\Visual Studio\Projects\MultipleCABFilesSetup\ MultipleCABFilesSetup \<project configuration>\ MultipleCABFilesSetup.msi. The default project configuration is Debug.
  2. Copy Custom Action Installer.msi, Setup.exe, and all other files and subdirectories in the directory to another computer.
    To install on a computer that is not on a network, copy the files to traditional media such as CD-ROM.
  3. On the target computer, make sure ActiveSync is installed, the target device is connected, and a partnership has been setup using ActiveSync, and then double-click Setup.exe to run the installer.

    At the end of installation, ActiveSync should start and should prompt you to install the two CAB files included in the setup project.

    You must have install permissions on the computer in order to run the installer.

To uninstall the application

  1. In Control Panel, double-click Add or Remove Programs.
  2. In the Add or Remove Programs dialog box, select MultipleCABFileSetup and click Remove.
    To uninstall from your development computer, with the MultipleCABFileSetup project open and selected in Solution Explorer, from the Project menu, click Uninstall.

License

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

Share

About the Author

Agola Kisira Odero
Software Developer (Senior)
Virgin Islands (British) Virgin Islands (British)
No Biography provided

Comments and Discussions

 
QuestionWindows 7 PinmemberSlaveMast3r2-May-13 4:24 
QuestionInstallation Role Pinmemberwebber9912-Dec-12 23:49 
GeneralMy vote of 5 PinmemberShreekanth Gaanji7-Nov-12 20:19 
QuestionNot installing PinmemberClyde19213-Sep-11 5:18 
AnswerRe: Not installing PinmemberAgola Kisira Odero13-Sep-11 14:18 
GeneralRe: Not installing PinmemberClyde19213-Sep-11 23:58 
GeneralRe: Not installing PinmemberClyde19214-Sep-11 3:40 
GeneralRe: Not installing PinmemberClyde19227-Sep-11 0:19 
GeneralMy vote of 5 Pinmemberfkautzmann8-Jul-10 4:26 
GeneralConvert it to vb.net Pinmembermr_cis11-May-10 20:06 
GeneralRe: Convert it to vb.net PinmemberAgola Kisira Odero12-May-10 5:08 
Generalsource code PinmemberAgola Kisira Odero13-Mar-10 14:17 
Questionsource code PinmemberSerge Desmedt13-Mar-10 10:27 
AnswerRe: source code PinmemberAgola Kisira Odero13-Mar-10 14:18 

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
Web01 | 2.8.141015.1 | Last Updated 13 Mar 2010
Article Copyright 2010 by Agola Kisira Odero
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid