Article
One Community, One World
Deploying a Smart Device Applications using .NET CF 2.0
by Ahmed Waly  on Jan 7 2007 12:00AM
  PageViews 11762   |    Add to Fav   |     Send to Friend   |    Download Code

Description:
Learn how to make a deployment project to deploy your application to smart devices.

Resources Used:
Microsoft Visual Studio 2005
.NET Compact Framework 2.0
.NET Compact Framework 2.0 SP1
Microsoft ActiveSync 3.8 or later (optional)  

Introduction:
Smart device application's deployment differs from desktop applications deployment. The Application Installation file for the smart deices in this case is Cab files, not Exe setup files, when you select a .cab file, the OS detects it and use it a deployment file.

How It Works?
We have several ways to make a deployment package for smart devices. First way, is by creating a smart device cab file, then copies it to the device, and run it from there, and it will be installed automatically. Other way, is by creating a deployment project to run from the desktop, in this case, you must have ActiveSync installed on the desktop, and the device is connected to the ActiveSync by any way, then run the .msi setup file from desktop, and it will send the cab to the device and run it there automatically. Here on this article, I'll explain how to make both ways, with sample code.

Let's Start...
Open Visual Studio 2005 and create a new smart device application project, add the controls and forms you need, and add the code behind of this controls.   Now, right click the solution from the solution explorer, and select Add New Project. 


Figure1: adding cab project  

In the dialog box, expand the "Other Projects Types" node, and select "Setup and Deployment" tree item, and select "Smart Device Cab Project", name it and press ok, like in the figure.  


Figure2: Selecting the cab project  

The cab project will be added to the solution. Right click the cab project and select Add Project Output, like in the figure.


Figure3: adding project output  

You should choose the project to add its output, in our sample, select the Application project and choose primary output from the list box and press OK.  

Note: you can add other items, like "Localized resources" if you are developing a localized application, or "Content files", if you are adding a content files to the project that will not be compiled with the project.    

Now, in the cab project properties, fill in its properties, as in figure.  


Figure4: setting cab project properties  

The OSVersionMin & OSVersionMax properties indicate the Windows Mobile versions that the application can be installed on.  

You can also add registry keys to be added to the device registry after deploying the application, from the cab project, right click and select view, and then Registry.


Figure5: adding registry keys to the project  

Right key the required key, and select new Key, name it and then right click on it and select New, and choose the type of new value, set its name and value. 


Figure6: adding registry values  

To add shortcuts to your application to any folder, select "Application Folder" from the left side, and right click the "Primary Output..." and choose create shortcut, a new shortcut will be created in the same directory, rename it to the app name, and move it to any folder you want from the left side folders explorer, for example, put it in "Programs Folder" to have a shortcut of your app in the Programs directory in the device. 


Figure7: adding shortcuts  

Now, just build the cab project, and it will generate the cab file automatically, and to test it, just copy it to the device, and run it from there, it will install the application, and u can find a shortcut in Programs folder.  

Well, this was the first and easiest way to make a deployment project for your application.   The Second way is to make .MSI deployment package, and run it from the desktop, and it will install it to your connected device by ActiveSync.   To use this way, you need to do all the previous steps, and do the following steps too.  

You need to add to the solution a new class library project, and name it CustomInstaller. Remove the auto generated class from the project, and right click the project and add new Installer Class, and name it CustomInstaller.cs  


Figure8: adding Class Library project 


Figure9: adding custom installer

The added class supports installation events, like BeforeInstall and AfterInstall, etc  

In the CustomInstaller,cs code, add the following events registration code to the constructor 

C#
public CustomInstaller()         
    {             
        InitializeComponent();               
        this.BeforeInstall += new InstallEventHandler(CustomInstaller_BeforeInstall);             
        this.BeforeUninstall += new InstallEventHandler(CustomInstaller_BeforeUninstall);             
        this.AfterInstall += new InstallEventHandler(CustomInstaller_AfterInstall);         
    } 



Now, add some variables to the class to define and use the destinations to used files, as shown in the code;   

C#
    //CE application manager path in the registry         
    public string CEAppManagerPath = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\CEAPPMGR.EXE"; 
        
    //ActiveSync Install Folder Path in registry         
    public string ActiveSyncDir = "SOFTWARE\\Microsoft\\Windows CE Services";         
    
    //Install Directory         
    public string INSTALLED_DIR = "InstalledDir";         

    //CE Application Manager File Name         
    public string CEAppManagerEXEFileName = "CEAPPMGR.EXE";         

    //CE Application Manager .ini file name         
    public string CEAppManagerINIFileName = "Deployment Sample.ini";         
    
    //Application's Directory             
    public string AppDir = "\\Deployment_Sample";         
    
    //System Temporary folder path         
    public string TempDir = Environment.SystemDirectory + "\\TEMP\\Deployment_Sample"; 



Then, add a method to get ActiveSync directory path from the registry, to use in in deploying the app to the device, as in code: 

C#
private string GetInstallDir()         
    {             
        RegistryKey ActiveSyncKey = Registry.LocalMachine.OpenSubKey(ActiveSyncDir);
             
        if (ActiveSyncKey == null)             
            {                 
                throw new Exception("ActiveSync is not installed on this PC!");             
            }                         

        // Create a directory inside ActiveSync folder for the deployment             
        string activeSyncPath = (string)ActiveSyncKey.GetValue(INSTALLED_DIR);             
        string installPath = activeSyncPath + AppDir;             
        ActiveSyncKey.Close();             
        return installPath;         
    } 



Now, add the folowing code the the events handlers we registered before: 

C#
void CustomInstaller_AfterInstall(object sender, InstallEventArgs e)         
    {             
        // Delete the temp install files after install finished (optional)             
        foreach (string tempFile in Directory.GetFiles(TempDir))             
            {                 
                File.Delete(tempFile);             
            }         
    }           

void CustomInstaller_BeforeUninstall(object sender, InstallEventArgs e)         
    {             
        // Find where the application is installed             
        string installPath = GetInstallDir();             
        
        // Delete the files             
        foreach (string appFile in Directory.GetFiles(installPath))             
            {                 
                File.Delete(appFile);             
            }             

        // Delete the folder             
        Directory.Delete(installPath);         
    }           

void CustomInstaller_BeforeInstall(object sender, InstallEventArgs e)         
    {             
        //* Here we get the install dir, create it, copy files to it, then run the             
        // CEAppmgr.exe to install the files from there.               
        // Find the location where the application will be installed             
        string installPath = GetInstallDir();             

        // Create the target directory             
        Directory.CreateDirectory(installPath);             
    
        // Copy your application files to the directory             
        foreach (string installFile in Directory.GetFiles(TempDir))             
            {                 
                File.Copy(installFile, Path.Combine(installPath, Path.GetFileName(installFile)), true);             
            }             

        // Get the path to ceappmgr.exe             
        RegistryKey keyAppMgr = Registry.LocalMachine.OpenSubKey(CEAppManagerPath);             
        string appMgrPath = (string)keyAppMgr.GetValue(null);             
        keyAppMgr.Close();             

        // Run CeAppMgr.exe to install the files to the device             
        System.Diagnostics.Process.Start(appMgrPath, "\"" + Path.Combine(installPath, CEAppManagerINIFileName) + "\"");         
    } 


Then build the Installer project to make the dll file to use next.  

Now, to create the MSI file, add a new setup project to the solution, and name it DeploymentSetup, set its properties as you like, or as in the figure:


Figure10: adding setup project 


Figure11: setting project properties

On the left side folders explorer, add new special folder, and choose System directory, and add sub folder name it temp, and another sub folder under temp folder name it "Deployment_Sample", to add to it the temp files.  

On the new added folder, right click and select add project output, and choose the cab project output, and the CustomInstaller output for the application Folder.  

Next, right click the project and select view, custom actions, then in the left side, right click and add custom action, open the Application folder from the shown dialog box, and select the CustomInstaller output and press yes.  

It will be added to all the folders in the custom action window.

Next, create new text file and name it "Deployment Sample.ini", add the following to it:

[CEAppManager]
Version      = 1.0
Component    = Innovation-Hut Deployment Sample  

[Innovation-Hut Deployment Sample]
Description  = Sample for the .NET CF Deployment Article
CabFiles     = DeploymentCab.cab 

And add this file to"Deployment_Sample" Sub folder in the left side folders explorer in the solution. 

Figure12: Solution explorer  

Now you are finished, build the project and use it, that's all.  

Cab or MSI?
It depends on the situation where you want to deploy your application. If it will be downloaded from the web, send by mail, Bluetooth, or any other way where it will be used from the device it self, then it must be a cab file.   But if it will be distributed commercially and depends on the PC or a connection or any other things that require the PC connection, or even ig the application size is large, then it can be installed from the desktop directly by ActiveSync.  

Conclusion:
Smart device application's deployment differs from desktop applications deployment in its structure and way of deploying. Applications can either be deployed by a cab file or MSI package from the desktop.    

More References:
MSDN: Deploying .NET Compact Framework 2.0 Applications with .cab and .msi Files 

Comments