65.9K
CodeProject 正在变化。 阅读更多。
Home

开发和部署Pocket PC安装应用程序

2004 年 1 月 21 日

11分钟阅读

viewsIcon

298557

downloadIcon

991

了解如何创建一个单一的 .msi 文件,该文件可从桌面运行,以在不同的 Pocket PC 设备上安装应用程序。开发过程已自动化,因此可以轻松地将所有必要的组件构建并打包到 .msi 文件中。提供了 C# 和 VB.NET 的示例代码。

本文由 MSDN 提供。

目录

概述

开发和部署 Pocket PC 应用程序时,以下是关键要点:

  • Pocket PC 设备有不同的处理器(ARM、SH3、MIPS 等)。
  • 应用程序使用 cabinet (.cab) 文件进行部署。
  • 每种处理器类型都需要一个不同的 .cab 文件。
  • Cab Wizard (cabwiz.exe) 会生成特定于处理器的 .cab 文件。
  • WinCE Application Manager 从桌面部署和安装 .cab 文件到 Pocket PC 设备。

首先讨论部署过程和卸载,然后讨论开发和自动化开发过程。

部署

用户可以通过复制并在设备上运行相应的 .cab 文件来安装 Pocket PC 应用程序,但更好的解决方案是通过在桌面上运行 .msi 文件来在设备上安装应用程序。此 .msi 文件会检测设备类型,将正确的 .cab 文件复制到设备,并通过运行 .cab 文件来安装应用程序。所有这些对用户来说都是透明的;他们只需在桌面上运行一个 .msi 文件,应用程序就会自动安装到 Pocket PC 上。

以下是基于 MSI 的部署涉及的步骤:

  • 用户在桌面上运行 .msi 文件。
  • .msi 文件会解压特定于处理器的 .cab 文件、setup.ini 和一个自定义安装程序组件。
  • 安装程序组件在安装过程中执行,它通过运行WinCE Application Manager 来部署和安装正确的 .cab 文件到设备。
  • setup.ini 文件向 WinCE Application Manager 描述应用程序。

下图显示了此过程中涉及的各个组件,然后是每个组件的信息。

图 1. 部署过程中涉及的组件

.msi 文件

.msi 文件是从桌面安装 Pocket PC 应用程序的单个文件。用户运行 .msi 文件,它会解压特定于处理器的 .cab 文件、一个自定义安装程序组件和一个 setup.ini 文件。

.cab 文件

Pocket PC 应用程序是通过在设备上运行 .cab 文件来安装的。这些是自解压文件,包含安装说明和应用程序所需的所有文件。文件是特定于处理器的,因此支持应用程序的每种处理器类型都需要一个单独的 .cab 文件。

安装程序组件

这是一个自定义安装程序组件,在安装过程中执行。它运行 WinCE Application Manager 来将正确的 .cab 文件复制并安装到设备。

Setup.ini 文件

此初始化文件向 WinCE Application Manager 描述应用程序,并通过应用程序管理器安装应用程序是必需的。

WinCE Application Manager

WinCE Application Manager (CeAppMgr.exe) 驻留在用户的桌面系统上,用于在 Pocket PC 设备上安装和卸载应用程序。下图显示了应用程序管理器提示用户在 Pocket PC 设备上安装示例应用程序。

图 2. 从桌面安装 Pocket PC 应用程序

卸载

.cab 文件将信息存储在 Pocket PC 上,以便可以卸载应用程序。用户可以直接通过 Pocket PC 或从桌面卸载应用程序。要通过 Pocket PC 卸载应用程序,用户需要从设置应用程序中选择添加/删除程序,如下图所示。

图 3. 使用 Pocket PC 卸载应用程序

与安装一样,用户也可以从其桌面卸载应用程序。他们从添加/删除程序控制面板应用程序中选择应用程序,然后单击删除按钮。这将执行自定义安装程序组件,该组件以卸载模式运行 WinCE Application Manager(不指定 setup.ini 文件)。用户取消选中该应用程序,然后单击确定将其从 Pocket PC 设备上卸载。

图 4. 从桌面卸载 Pocket PC 应用程序

开发

开发目标是以最少的工作量(最好是一键式)生成 .msi 文件。首先,让我们看看开发过程中涉及的组件:

  • BuildCab.bat 文件通过运行 Cab Wizard 来启动该过程。
  • 信息文件 (.inf) 向 Cab Wizard 描述应用程序。
  • Cab Wizard 会为 .inf 文件中指定的处理器类型生成不同的 .cab 文件。
  • .cab 文件,以及自定义安装程序组件和 setup.ini 文件,被打包到一个 .msi 文件中。

下图显示了此过程中涉及的各个组件,然后是每个组件的信息。

图 5. 开发过程中涉及的组件

BuildCab.bat

BuildCab.bat 文件通过运行 Cab Wizard 工具来构建特定于处理器的 .cab 文件。当您从生成菜单中选择生成 CAB 文件时,Visual Studio 会生成一个模板 BuildCab.bat 文件。最好让 Microsoft® Visual Studio® 生成此文件,然后将其复制到另一个位置并进行任何修改。最有可能的是,唯一需要的更改是为 .cab 文件和日志文件指定新路径。下面显示了示例 BuildCab.bat

"C:\Program Files\Microsoft Visual Studio .NET 
  2003\CompactFrameworkSDK\v1.0.5000\Windows CE\..\bin\..\bin\cabwiz.exe" 
  "c:\program files\pocketpc deploy 
  sample\Source\CS\PocketApp\BuildCabs\PocketApp_PPC.inf" /dest 
  "c:\program files\pocketpc deploy 
  sample\Source\CS\PocketApp\BuildCabs\Cabs" /err CabWiz.PPC.log /cpu 
  ARMV4 ARM SH3 MIPS X86 WCE420X86

信息文件 (.inf)

Microsoft Windows® CE .NET .inf 文件向 Cab Wizard 指定安装设置和应用程序文件。与 BuildCab.bat 文件一样,当选择生成 CAB 文件时,Visual Studio 会生成一个模板 .inf 文件。您应该首先使用 Visual Studio 生成此文件,然后将其复制到另一个位置以进行任何修改。该文件通常需要最少的修改;通常只需更新提供商名称。

Visual Studio 生成的 .inf 文件包含对 vsd_setup.dll 的引用。此组件用于版本检查,并在 Pocket PC 设备上未安装正确版本的 .NET Compact Framework 时报告信息。最好将其保留在您的应用程序中,但为简化起见,已将其从示例代码中删除。

下面是一个示例文件。您可以访问 Microsoft Windows CE .NET:创建 .inf 文件 以获取有关 .inf 文件的更多信息。

[Version]
Signature="$Windows NT$"
Provider="Sample Company"
CESignature="$Windows CE$"

[CEStrings]
AppName="PocketApp"
InstallDir=%CE1%\%AppName%

[CEDevice]
VersionMin=3.00
VersionMax=4.99

[DefaultInstall]
CEShortcuts=Shortcuts
CopyFiles=Files.Common

[SourceDisksNames]
1=,"Common1",,"C:\Code\Microsoft\Pocket PC 
  Whitepapers\Deployment\Code\CS\PocketApp\obj\Release\"

[SourceDisksFiles]
PocketApp.exe=1

[DestinationDirs]
Files.Common=0,%InstallDir%
Shortcuts=0,%CE2%\Start Menu

[Files.Common]
PocketApp.exe,,,0

[Shortcuts]
PocketApp,0,PocketApp.exe,%CE11%

Cab Wizard

Cab Wizard (cabwiz.exe) 会生成可安装在不同 Pocket PC 设备上的 .cab 文件。.inf 文件用于向向导描述应用程序,并作为命令行上的第一个参数传递。其他可选参数是目标目录、错误日志文件和 CPU 类型。您可以访问 Microsoft Windows CE .NET:CAB Wizard 语法 以获取有关运行向导的更多信息。

安装程序组件

自定义安装程序组件通过处理 AfterInstallAfterUninstall 事件并运行 WinCE Application Manager 来自动化部署过程。应用程序管理器的路径存储在注册表下的 HKLM\software\Microsoft\Windows\CurrentVersion\App Paths\CEAppMgr.exe 注册表项中。下面显示了 AfterInstallAfterUninstall 事件的代码。

C#

private void Installer_AfterInstall(object sender,
   System.Configuration.Install.InstallEventArgs e)
{
   // get fullpath to .ini file
   string arg = Path.Combine(
      Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
      "Setup.ini");

   // run WinCE App Manager to install .cab file on device
   RunAppManager(arg);
}

private void Installer_AfterUninstall(object sender, 
  System.Configuration.Install.InstallEventArgs e)
{
   // run app manager in uninstall mode (without any arguments)
   RunAppManager(null);
}

private void RunAppManager(string arg)
{
   // get path to the app manager
   const string RegPath = @"Software\Microsoft\Windows\" +
      @"CurrentVersion\App Paths\CEAppMgr.exe";

   RegistryKey key = Registry.LocalMachine.OpenSubKey(RegPath);
   string appManager = key.GetValue("") as string;
   
   if (appManager != null)
   {
      // launch the app
      Process.Start(
         string.Format("\"{0}\"", appManager), 
         (arg == null) ? "" : string.Format("\"{0}\"", arg));
   }
   else
   {
      // could not locate app manager
      MessageBox.Show("Could not launch the WinCE Application Manager.");
   }
}

VB.NET

Private Sub Installer_AfterInstall(ByVal sender As Object, _
   ByVal e As System.Configuration.Install.InstallEventArgs) _
   Handles MyBase.AfterInstall

   ' get fullpath to .ini file
   Dim arg As String = Path.Combine(Path.GetDirectoryName( _
      System.Reflection.Assembly.GetExecutingAssembly().Location), _
      "Setup.ini")

   ' run WinCE App Manager to install .cab file on device
   RunAppManager(arg)
End Sub

Private Sub Installer_AfterUninstall(ByVal sender As Object, _
   ByVal e As System.Configuration.Install.InstallEventArgs) _
   Handles MyBase.AfterUninstall
   ' run app manager in uninstall mode (without any arguments)
   RunAppManager(Nothing)
End Sub

Private Sub RunAppManager(ByVal arg As String)
   ' get path to the app manager
   Const RegPath As String = "Software\Microsoft\Windows\" & _
      "CurrentVersion\App Paths\CEAppMgr.exe"

   Dim key As RegistryKey = Registry.LocalMachine.OpenSubKey(RegPath)
   Dim appManager As String = CStr(key.GetValue(""))

   If Not (appManager Is Nothing) Then
      If arg Is Nothing Then
      Process.Start(String.Format("""{0}""", appManager))
      Else
         ' launch the app
         Process.Start( _
            String.Format("""{0}""", appManager), _
            String.Format("""{0}""", arg))
      End If
   Else
      ' could not locate app manager
      MessageBox.Show("Could not find app manager")
   End If
End Sub

Setup.ini 文件

.ini 文件描述了 Pocket PC 应用程序,在使用 WinCE Application Manager 将应用程序部署到 Pocket PC 设备时是必需的。下面显示了示例 setup.ini 文件。您应该在您的应用程序中设置 VersionDescriptionCabFiles 属性。您可以访问 Microsoft Windows CE 3.0:为应用程序管理器创建 .ini 文件以获取有关 .ini 文件的更多信息。

[CEAppManager]
Version      = 1.0
Component    = App

[App]
Description  = Sample Pocket PC application.
CabFiles     = 
  PocketApp_PPC.X86.CAB,PocketApp_PPC.ARM.CAB,PocketApp_PPC.ARMV4.CAB,
  PocketApp_PPC.MIPS.CAB,PocketApp_PPC.SH3.CAB,PocketApp_PPC.WCE420X86.CAB

.msi 文件

这是分发给用户的最终文件。它包含从桌面将 Pocket PC 应用程序部署到不同 Pocket PC 设备所需的所有内容。

自动化开发过程

现在您已经熟悉了开发过程中涉及的所有组件,让我们看看如何自动化构建。关键点是:

  • 创建一个包含多个项目的解决方案(Pocket PC 应用、自定义安装程序和设置)。
  • 将安装程序组件作为安装卸载自定义操作添加到设置项目中。
  • 使用预生成事件调用 BuildCab.bat 文件来生成 .cab 文件。
  • 指定项目依赖项,以便项目按正确的顺序构建。
  • 使用配置管理器为调试构建构建 Pocket PC 应用程序,并为发布构建构建所有项目。

下一节将更详细地讨论 C# 和 Microsoft Visual Basic® .NET 示例解决方案。C# 解决方案一键构建所有项目(Pocket PC 应用、自定义安装程序和 .msi 文件)。Visual Basic.NET 需要更多步骤,因为 Microsoft Visual Studio® 缺少这两个功能。

  1. 一个解决方案不能包含针对不同平台的 VB.NET 项目(Pocket PC 应用不能与自定义安装程序组件在同一个解决方案中)。
  2. 预生成和后生成事件不支持任何 VB.NET 项目。

VB.NET 解决方案仍然是自动化的,只是不如 C# 版本自动化。

解决方案和项目

C# 解决方案包含三个项目:Pocket PC App、Custom Installer 和 Setup。PocketApp 项目是一个 Smart Device 应用程序,包含 Pocket PC 代码。CustomInstaller 项目是自定义安装程序组件,而Setup 项目将所有内容打包到一个 .msi 文件中。下面显示了 C# 解决方案。

图 6. 包含 Pocket PC、安装程序组件和设置项目的 C# 解决方案

VB.NET 需要两个解决方案。第一个包含名为PocketApp 的 Smart Device 项目。第二个解决方案生成 .msi 文件,并包含CustomInstallerPre-BuildSetup 项目。CustomInstaller 和 Setup 项目等同于 C# 项目,Pre-Build 项目是C++ Makefile 项目;它不包含任何 C++ 代码,仅用于指定预生成事件。下面显示了 VB 解决方案。

图 7. 包含 Pocket PC、安装程序组件、预生成和设置项目的 VB.NET 解决方案

PocketApp 项目

PocketApp 项目是一个简单的 Smart Device,“hello world”应用程序;是您的 Pocket PC 项目的占位符。BuildCab.batPocketApp_PPC.inf 文件用于构建 .cab 文件,而 setup.ini 文件用于部署应用程序。app.ico 文件是应用程序图标,显示在 Pocket PC 的“程序”组中。下面显示了 C# 和 VB.NET 版本的应用程序图标设置。

图 8. 在 C# 中设置应用程序图标

图 9. 在 VB.NET 中设置应用程序图标

图 10. 图标显示在 Pocket PC 的“程序”组中

CustomInstaller 项目

这是运行 WinCE Application Manager 以将 .cab 文件部署到 Pocket PC 设备的组件。本文前面展示了 C# 和 VB.NET 版本的代码。

Setup 项目

Setup 项目生成一个 .msi 文件,其中包含特定于处理器的 .cab 文件、安装程序组件和 setup.ini 文件。CustomerInstaller 组件被添加为安装卸载自定义操作,如下所示。

图 11. 添加安装和卸载自定义操作

预生成事件

在 PocketApp 项目生成后,您需要运行 BuildCab.bat 文件来生成 .cab 文件。Visual Studio 不允许为 C# Smart Device 项目指定后生成事件,因此我们采取了次优方案,为 CustomInstaller 项目定义了一个预生成事件。

图 12. 在 C# 中使用预生成事件构建 .cab 文件

Visual Studio 不允许为 VB.NET 项目设置任何生成事件,因此使用 C++ Makefile 项目来定义预生成事件,如下所示。

图 13. 为 VB.NET 解决方案使用 C++ 预生成事件

项目依赖项

设置正确的生成顺序很重要,因为解决方案包含多个项目。对于 C#,生成顺序设置为 PocketApp、CustomInstaller 和 Setup,如下所示。

图 14. 为 C# 解决方案设置生成顺序

VB.NET 版本包含两个解决方案;应首先构建 PocketApp 解决方案,然后构建 PocketPCSetup 解决方案。下面显示了设置解决方案的生成顺序。

图 15. 为 VB.NET 解决方案设置生成顺序

配置管理器

Configuration Manager 用于以调试模式构建 Pocket PC 项目,并以发布模式构建所有项目。这样,您就不必经历整个构建过程来调试 Pocket PC 应用程序。下面显示了 C# 版本。

VB.NET 版本不需要这样做,因为它有一个用于 Pocket PC 应用的解决方案,以及另一个用于生成 .msi 文件的解决方案。

图 16. 仅以调试模式构建 Pocket PC 项目

图 17. 以发布模式构建所有项目

安装和构建示例解决方案

以下是有关安装和构建示例解决方案的说明:

  • 运行 PocketPC Deploy Sample.msi 文件将 C# 和 VB.NET 解决方案安装到您的系统。指向 Visual Studio 解决方案文件的链接将添加到“开始”菜单的PocketPC Deploy Sample 组下。
  • BuildCab.batPocketApp_PPC.inf 文件中的硬编码路径已更新以匹配您的系统(指向示例安装文件夹和 Visual Studio 的路径)。如果您在构建示例时遇到问题,应仔细检查这些文件中的路径信息。
  • 选择发布模式以构建所有项目(调试模式仅构建 Pocket PC 应用)。
  • .msi 文件名为 PocketApp Setup.msi,它创建在 Setup\Release 文件夹中。

链接

© . All rights reserved.