如何部署.NET Compact Framework2.0 应用程序到Windows Mobile(制作CAB文件)

来源:互联网 发布:lrc字幕制作软件 编辑:程序博客网 时间:2024/05/28 15:37
Deploying .NET Compact Framework 2.0 Applications with .cab and .msi Files

 

Christopher Tacke
OpenNETCF Consulting

December 2005

Applies to:
   Microsoft .NET Compact Framework version 2.0
   Windows Mobile version 5.0
   Microsoft Windows CE
   Microsoft ActiveSync
   Microsoft Visual Studio 2005

Summary:Learn how to deploy your application to Windows Mobile–based devices byusing Visual Studio 2005 to create device .cab files and by creating adesktop computer Microsoft Installer Package. (19 printed pages)


Download Deploy_CF2_Apps_Cab_Msi.msi from the Microsoft Download Center.

Contents

Introduction
Device Deployment Overview
Creating Device .cab Files with Visual Studio
Creating a Desktop Computer Microsoft Installer Package
Conclusion

Introduction

Soyou've written the next best-selling embedded application. The nextstep is to get it into the hands of users and onto their devices. Witha desktop computer application, it's pretty simple—you create adeployment package project that generates a Microsoft Installer (MSI)package, and distribute the .msi package. Unfortunately, it's not quiteas simple for a device. In this article, you will find out what aWindows Mobile–based device needs to install an application, how to useMicrosoft ActiveSync to make distributing easier, and how to useMicrosoft Visual Studio 2005 to make the entire process seamless.

Deployingan application to a device has a lot more variables than deploying asimple desktop computer application, yet the process needs to be justas simple for the user. To make a device deployment as simple asdesktop computer deployment, it's important to understand the overallprocess and then all of the variables that come into play. After youunderstand the process and the variables, you can put together anydeployment—no matter how complex the underlying system gets.

Thereare essentially three major systems involved with a device deployment.The first is the desktop computer; the second is Microsoft ActiveSync;and the third is the device .cab file extractor application calledwceload.exe. Add to these systems the potential mix of differentprocessors in addition to a mix of managed and unmanaged code, andyou've got the deployment landscape. This article will guide youthrough this landscape, starting with the device.

Device Deployment Overview

Tothe user, a device deployment is no different than a desktop computerapplication deployment. The user downloads or receives an .msi file andruns it on his or her desktop computer. The Microsoft Installer walksthe user through a few wizard screens and then the application isinstalled.

From a developer's point of view, however, the .msifile is only the final step of many in creating the deployment package.A Windows Mobile–based device cannot use an .msi file directly, but itinstead requires a .cab file to perform a program installation. For the.msi file to be useful to the user, the developer must programmaticallyinstruct the ActiveSync Application Manager to copy the .cab file tothe device with the option of allowing the user to deploy to more thanone device or remove the file later.

To achieve a friendly, user-expected installation experience, you will have to complete the following steps:

  1. Create .cab files for the target device.
  2. Add your application files and registry entries to the .cab files.
  3. Register the .cab file with ActiveSync, so it can deploy from the desktop computer.
  4. Provide the code for any custom actions that the installer file must make during installation or uninstallation.
  5. Pack all of this information—and anything else the application needs—into a single distributable .msi file.

This article takes you through each of these steps using a real-world example of deploying the OpenNETCF WiFiDiscovery application.

Creating Device .cab Files with Visual Studio

Whenyou create the deployment package, you need to generate the .cab filesthat actually get installed on the targeted device. If you haveexperience with device development—or even installed many third-partyapplications on your device—you're probably familiar with .cab files.Essentially a .cab file is a compressed file that contains theapplication's file, any necessary registry entries, and some stringresources for the on-device installer. The .cab file itself isuncompressed and interpreted by wceload.exe, which exists on allPocket PC and Windows Mobile–based Smartphone devices—in addition tomany generic Windows CE devices.

Because Windows CE–baseddevices can differ in their operating system versions in addition totheir processor architectures, some application install packagescontain several .cab files—one for each permutation of processor andoperating system version that the device supports. For example, theMicrosoft .NET Compact Framework version 2.0 itself has seven .cabfiles.

At this point, you may be tempted to ask, "But managedapplications use Microsoft Intermediate Language (MSIL), which isprocessor independent. Why can't there just be one .cab file?" This isa good and very valid question. Microsoft Visual Studio .NET 2003 wouldalways create several .cab files when you chose to have it generatethem. The reason is that an installer .cab file may contain a filecalled setup.dll that contains special instructions for the installerto run when the application is installed or uninstalled. This .dll filemust be written in unmanaged code, and because of that fact, there mustbe different installs for the processor types and operating systemversions.

Fortunately, if your application has no special needs,you don't need the setup.dll file—a single .cab file will work. Theexamples in this article work with a single .cab file.

You needto add a Smart Device Cab Project to your application's solution. Forthis example, the project is named DeploymentCAB, as shown in Figure 1.

Click here for larger image

Figure 1. Adding a new Smart Device Cab Project to your application's solution

Next,you need to add files to the cab project. You can add files in a coupleof ways: you can select an individual file you want to deploy, or youcan select another project in the solution and have its output added tothe .cab file. Explicit selection of each file to deploy would work forevery file, but being able to add a project output is useful because itmakes it easier to keep the cab project contents current with projectchanges, and it automatically adds all detected references. Solution Explorer, right-click the DeploymentCAB project, select Add, and then click Project Output. The dialog box in Figure 2 appears.

Figure 2. Add the output of your application project to the cab project

Inthis example, the application project is referencing the OpenNETCFSmart Device Framework libraries, which are automatically pulled in, asshown in Figure 3.

Figure 3. Project output and dependencies shown in Solution Explorer

Thisproject was named DeploymentCAB because when looking at the solution,it's self-descriptive. However, Visual Studio 2005 uses the projectname as the default name for the generated .cab file. Deploying a .cabfile called DeploymentCAB.cab isn't terribly friendly, so you can alterthe project properties to alter the actual output file name, as shownin Figure 4.

Click here for larger image

Figure 4. Change the name of the generated .cab file

Keep in mind that this change only affects the output file name, and you must change it by selecting the project in Solution Explorer, and then, on the Project menu, click Properties. It's a bit counterintuitive that you cannot change the output file name in the Visual Studio Properties pane. The settings in the Properties pane affect how the ActiveSync installer user interface (UI) will present information, like Product Name and Company.

A.cab file is actually generated by an application called cabwiz.exe onthe desktop computer, even in the Smart Device Cab Project. VisualStudio simply calls to cabwiz.exe to generate the actual files. Theinformation about the files and registry changes that go into the .cabfile—along with text to display—is contained in an .inf file, whichVisual Studio generates based on your cab project's settings.

Thereis plenty of documentation online about the exact format of the .inffile, so this article will not go into detail about it, but it'simportant to know that changes to the Properties pane (which is shown in Figure 5) are reflected in the .inf file. For example, modifying the Product Name entry in the Properties pane generates a line in the output .inf file. This article will explain where that information gets generated a little later.

Figure 5. Modify Properties for setting install text

As mentioned previously in this article, you can add registry entries into the .cab file as well. In the Solution Explorer, simply click the Registry Editoricon to open the editor UI, and then make the modifications. Figure 6shows an example of adding a version number to the registry for theWiFiDiscovery application. Remember that entries you put into the SmartDevice Cab Project get applied to the targeted device—not theinstalling desktop computer. If you need registry entries on thedesktop computer, those entries are done in one of the other projects.

Click here for larger image

Figure 6. Add the install's device registry entries

After you've added all of the files and registry entries to your project and you've adjusted the Propertiespane to reflect the information you want displayed by ActiveSync andthe device .cab file installer, you can build the project. It generatesoutputs that are similar to those in Figure 7: a .cab file, a .log file(which is useful if the build fails), and the .inf file.

Click here for larger image

Figure 7. Output files from the cab project

Ifyou find that during your tests the device-side installation processdoesn't go quite as expected, such as incorrect dialog captions,missing files, or incorrect or missing device registry settings, the.inf file is the place to begin debugging the behavior. Visual Studio2005 provides a friendly UI for generating the .cab files, but it's theactual .inf file that cabwiz.exe uses to actually generate the .cabfiles, and all .cab file behavior will be reflected in the .inf file.

Afteryou've verified that the .cab file was generated, you're done with thispart of the deployment package. Next, this article describes the piecesfor the desktop computer.

Creating a Desktop Computer Microsoft Installer Package

Providinga .cab file for download is one way to distribute your application, butmost users won't know what to do with it, leading to support calls (thebest scenario) or lost customers (the worst scenario). The desktopcomputer installer package is where the "magic" that makes theinstallation friendly and professional looking to the user happens.

Fordevice applications, there are two things that the installer needs todo: it must present the user with the usual wizard screens for theinstallation, and it also must deploy the application to a connecteddevice without requiring the user to take additional steps. In thissection, you'll look at both of these things.

Registering with ActiveSync

ActiveSynchandles installing applications to a connected Windows Mobile–baseddevice by using an application called CeAppMgr.exe, which is installedonto the desktop computer as part of the ActiveSync application.CeAppMgr.exe requires an .ini file for an application to be registeredwith it for deployment, and unfortunately, this .ini file must begenerated manually. Fortunately, it's not a complex file format.

Note   Whenyou're generating and testing your .ini files, it can be extremelyhelpful to turn on debug output from CeAppMgr.exe, which providessimple MessageBox outputs that report how it is parsing the .ini file.

To turn on debugging, set the following registry key on your desktop computer.

[HKLM/Software/Microsoft/Windows CE Services/AppMgr]
"ReportErrors"=dword:1

The following code example is the .ini file thatis used for registering WiFiDiscovery. Note that line numbers wereadded for reference only—your .ini file should not have them.

01  [CEAppManager]
02 Version = 1.0
03 Component = OpenNETCF WiFiDiscovery
04
05 [OpenNETCF WiFiDiscovery]
06 Description = Sample WiFi Network Discovery Application using the
SDF
07 CabFiles = WiFiDiscovery.cab

Line 01 denotes that this is an .ini file for CeAppMgr.exe. This line is required.

Line 02 denotes the version of CeAppMgr.exe that this file supports. It is not the version of your application.

Line03 denotes the component name. The name used in this line of code mustappear in square brackets later in the file (in this case, thislocation is on line 05).

Line 05 starts the component description section.

Line06 provides the text that will be displayed as the program descriptionin the ActiveSync installer UI on the screen (you'll see this later inFigure 17 when you test the deployment package).

Line 7enumerates all of the .cab files that are used for this installation ina comma-separated list. This line must not have any spaces in it.

Asyou learned earlier, .cab files internally hold the processor andoperating system version they support, so you simply need to list allof the .cab files. ActiveSync will know which cab file to use. Thesefiles can also be in subdirectories; if you choose to usesubdirectories, the .cab file names use a relative path from theActiveSync install folder (this topic will be discussed more later).

Custom Actions During Installation

Again,because you're trying to make your installation friendly andprofessional, you want to follow some basic guidelines and standards.Applications registered with CeAppMgr.exe for installation usually arein a subfolder of the ActiveSync installation folder (in fact, Designed for Windows Mobile logo certification requires that you put your application in this location).

Becausea user could have installed ActiveSync in a different location andbecause you don't want the user to have an option to install yourapplication files in a location that ActiveSync can't find, you needyour installation to determine where this path is and automatically putthe necessary files where they should be. To achieve this, you'll use afeature of the Microsoft Installer that allows you to provide a classlibrary that exports some custom actions that get automatically run atcertain points during the installation process. In fact, you'll usethis mechanism to launch CEAppMgr.exe with your .ini file as well.

Youneed to simply add a new Windows Class Library project to theapplication solution, as shown in Figure 8; for this example, it isnamed InstallerDLL.

Click here for larger image

Figure 8. Add a new Windows Class Library project

Youwon't be using the default wizard generated Class1, so delete it.Instead, you'll be using a custom installer class, which is a specialtype. Of course, if you need a complex installation process, you canadd the generic classes for use—you just won't be doing anything thatcomplex in this sample.

To add the new custom installer class to the InstallerDLL project (in Solution Explorer, right-click the InstallerDll project, point to Add, and then click New Item), as shown in Figure 9.

Click here for larger image

Figure 9. Add an installer class to the project

The installer class supports several events that are related to installation and uninstallation. For this example, you'll use BeforeInstall to copy your files to the ActiveSync folder and register with CEAppMgr.exe, AfterInstall to clean up the files from the install path (you don't need to keep needless duplicate files), and BeforeUninstallto remove the files from the ActiveSync folder because the automaticuninstaller doesn't know about files that you've copied elsewhere.

Register each of the events you're interested in handling in the class constructor, as shown in the following code example.

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

You need to define some constants for use throughout the code, as shown in the following code example.

private const string CEAPPMGR_PATH = 
@"SOFTWARE/Microsoft/Windows/CurrentVersion/App Paths/CEAPPMGR.EXE";
private const string ACTIVESYNC_INSTALL_PATH =
@"SOFTWARE/Microsoft/Windows CE Services";
private const string INSTALLED_DIR = "InstalledDir";
private const string CEAPPMGR_EXE_FILE = @"CEAPPMGR.EXE";
private const string CEAPPMGR_INI_FILE = @"WiFiDiscovery.ini";
private const string APP_SUBDIR = @"/OpenNETCF WiFiDiscovery";
private string TEMP_PATH =
Environment.SystemDirectory + @"/TEMP/WiFiDiscovery";

Because you will need to know where ActiveSync isinstalled so that you can install and uninstall your application, youneed a helper method to extract this information from the registry, asshown in the following code example.

private string GetAppInstallDirectory()
{
// Get the ActiveSync install directory
RegistryKey keyActiveSync =
Registry.LocalMachine.OpenSubKey(ACTIVESYNC_INSTALL_PATH);
if (keyActiveSync == null)
{
throw new Exception("ActiveSync is not installed.");
}
// Build the target directory path under the ActiveSync folder
string activeSyncPath =
(string)keyActiveSync.GetValue(INSTALLED_DIR);
string installPath = activeSyncPath + APP_SUBDIR;
keyActiveSync.Close();
return installPath;
}

Next, look at the event handlers. Before youinstall the application, you need to determine the path so yourinstallation folder will be under the ActiveSync folder. You candetermine this path by calling the GetAppInstallDirectory method as shown in the previous code example, and then you can copy all of your application files to that directory.

Afteryou've copied the application files, you have to determine whereCeAppMgr.exe is installed—again, you can retrieve this information fromthe registry. You will call CeAppMgr.exe with the fully qualified pathof your .ini file as a parameter, and this step will register yourapplication and start the ActiveSync installation wizard, as shown inthe following code example.

void CustomInstaller_BeforeInstall(object sender, InstallEventArgs e)
{
// Find the location where the application will be installed
string installPath = GetAppInstallDirectory();
// Create the target directory
Directory.CreateDirectory(installPath);
// Copy your application files to the directory
foreach (string installFile in Directory.GetFiles(TEMP_PATH))
{
File.Copy(installFile, Path.Combine(installPath,
Path.GetFileName(installFile)), true);
}
// Get the path to ceappmgr.exe
RegistryKey keyAppMgr =
Registry.LocalMachine.OpenSubKey(CEAPPMGR_PATH);
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, CEAPPMGR_INI_FILE) + "/"");
}

After you've installed your application in theActiveSync folder, you want to remove the files from the temporaryfolder you initially installed them in, as shown in the following codeexample.

void CustomInstaller_AfterInstall(object sender, InstallEventArgs e)
{
// Delete the temp files
foreach (string tempFile in Directory.GetFiles(TEMP_PATH))
{
File.Delete(tempFile);
}
}

That completes the custom installation procedure,but because you've moved files during the installation process, theMicrosoft Installer has no idea they exist, so you must manually removethem. This requires a custom action for the uninstallation as well.Again, you determine the directory where the files were copied, andthen you iterate through the code and delete each of the files, asshown in the following code example.

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

After you have all of your event handlerswritten, all you need to do is compile the InstallerDLL project togenerate a class library that you'll use in the final step.

Creating the MSI

Nowfor the final step: creating the actual .msi file. This section focuseson the device-specific information and leaves topics like wizard UImodifications and the like as exercises for the reader.

Note   For detailed information about creating Microsoft Installer Packages with Visual Studio, see the Visual Studio Installer Reference.

First,add a new setup project to the existing solution as shown in Figure 10.For this example, the setup project is named DeploymentMSI.

Click here for larger image

Figure 10. Add a setup project to the solution

Again, it's a good practice to update the Properties pane for the Application Name, Company, SupportUrl and the like. These items get displayed on the desktop computer during the Install Wizard progression.

AgainVisual Studio sets the default output file name to the project name,which is often not very user friendly, so you should click the Project menu, and then select the Properties command to open the dialog box that is shown in Figure 11. On this dialog box, set the output file name.

Click here for larger image

Figure 11. Set the property for the output file name

Next,you need to choose the location on the desktop computer for theinstallation files. As you may recall, you have to eventually put thefiles in a subfolder of ActiveSync, and you won't know that locationuntil the installer is run (and then, you will only know that locationthrough a custom action), so you'll simply place the files in atemporary folder you will create in the Windows System folder calledWiFiDiscovery. Use the File System Explorer in the Installer Project togenerate the new folder, as shown in Figure 12.

Click here for larger image

Figure 12. Add the System folder to your project

Afteryou have the folder, you can add any file content to it. Again, to makethings simple, you can add the output of another project in yoursolution instead of an explicit file. Figure 13 shows the dialog boxfor adding the InstallerCAB project output.

Figure 13. Add the cab project output to the installer

Next,you need to set up the .msi file to use the custom actions that youcreated in the InstallerDLL project. Open the Custom Actions Editor byusing the shortcut menu (right-click the DeploymentMSI project, andthen click Custom Action) or by clicking the Custom Actions Editor icon at the top of the Solution Explorer, and then select Add Custom Action.

Select your newly created temporary folder, and then use the Add Project Output Group dialog box that is shown in Figure 14 to add the output of the InstallerDLL project.

Figure 14. Add the custom installer DLL to the installer

Byadding a custom action DLL, you're tying your custom code to thedesktop computer .msi file extractor, which will call into your customDLL when it is run by the user and perform any actions you tell it to.This addition provides you almost limitless flexibility to make aninstallation perform operations that are necessary for your applicationto install perfectly.

After you've added the output, verify thatthe custom installer has been added to the project by ensuring itappears in the dialog box that is shown in Figure 15.

Click here for larger image

Figure 15. Verify that the custom installer has been added

The Custom Action Explorer should show the output of InstallerDLL being used for all actions, as shown in Figure 16.

Click here for larger image

Figure 16. Custom Actions applied to installer

Finally,you need to add the .ini file that CeAppMgr.exe uses as an explicitfile, and then your project is complete and ready to be used to createyour program's Microsoft Installer Package, as shown in Figure 17.

Click here for larger image

Figure 17. All Files added to the installer

Makesure you've built all of the other projects in the solution, and thenbuild the DeploymentMSI project to create the output .msi file.

Finally,you can test the installer from end to end. Make sure you either haveyour Windows Mobile–based device connected by means of ActiveSync oryou have one of Visual Studio 2005's device emulator's selected ascradled. In the Solution Explorer, right-click the DeploymentMSI project, and then select Install from the shortcut menu (you'll also see Uninstallas an option, which is useful for testing the package's uninstallprocesses). If all goes well, the Installer Wizard opens, and after youfollow the instructions in the wizard, CeAppMgr.exe opens theinstallation dialog box, as shown in Figure 18.

Click here for larger image

Figure 18. ActiveSync's Application Manager

Ifyou follow the instructions on the dialog boxes that open on thedevice, the WiFiDiscovery application will be installed on your mobiledevice.

Conclusion

Deploying a mobile device application is still not a simple point-and-click process—especially if you want to get logo certificationfor your application and make installing your application easy for yourusers. In this article, you learned the basic steps that are necessaryfor a typical installation. By no means does this article cover everypossibility or contingency, but, depending on the complexity of yourapplication's deployment needs, the topics in this article shouldeither be everything you need for your installation, or they shouldprovide a solid foundation that you can modify. When you need to workon the deployment package for your next application, you'll at leastknow the path to follow for a successful rollout.

原创粉丝点击