Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9599835
  • 博文数量: 1227
  • 博客积分: 10026
  • 博客等级: 上将
  • 技术积分: 20273
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-16 12:40
文章分类

全部博文(1227)

文章存档

2010年(1)

2008年(1226)

我的朋友

分类: C/C++

2008-04-02 18:30:18

下载本文示例代码
应用
Microsoft® .NET Compact Framework 1.0
Microsoft Visual Studio® .NET 2003

概要

  了解如何创建独立的 .msi 文件,该文件从桌面运行以便将应用程序安装到不同的 Pocket PC 设备上。开发过程是自动化的,所以能轻松创建和打包所需组件到一个 .msi 文件。示例代码用 C# 和 VB.NET 语言编写。

下载源代码

内容提要



下面所列为开发和部署 Pocket PC 应用程序的要点:

  • Pocket PC 设备有不同的处理器类型(如:ARM,SH3,MIPS 等)。
  • 应用程序用 .Cab 文件格式部署。
  • Cab 向导(cabwiz.Exe)生成特定处理器的.cab文件。
  • WinCE 应用程序管理器从桌面部署和安装.cab文件到 Pocket PC 设备上。

我们首先论述部署和卸载过程,然后是开发和开发过程的自动化。



  一般用户可以通过拷贝和运行合适的.cab文件到他们的设备上来安装 Pocket PC 应用程序,但是有一个更好的解决方案是从桌面运行 .msi 文件 来安装应用程序到其设备。该.msi文件检测设备类型,拷贝正确的.cab文件到设备上,然后运行这个.cab文件安装应用程序。所有的过程都对用户透明,用户只要 在其桌面运行.msi文件,应用程序就可以被自动安装到 Pocket PC 上。

下面是基于 .msi 部署涉及的步骤:

  • 用户在他们的桌面运行 .msi 文件。
  • msi 文件解包成特定处理器的 .cab 文件,setup.ini 和一个定制的安装程序组件。
  • 安装过程中安装程序组件被调用,通过运行WinCE应用程序管理器(WinCE Application Manager)将正确的 .cab 文件部署和安装到设备上。
  • Setup.ini 文件向 WinCE 应用程序管理器提供应用程序的描述信息。

下图说明了与部署过程相关的各部分,接着是每个部分的描述信息。


图一 包含在部署过程中的各个模块

.msi 文件
  .msi文件是可以从桌面安装你的 Pocket PC 应用程序的独立文件。用户运行.msi文件,它解包成特定处理器的.cab文件,一个自定义安装组件,和一个setup.ini文件。

.cab文件

  通过运行.cab文件把Pocket PC应用程序安装在设备上。这些文件是自解压文件,包含有安装指令和应用程序所需的所有文件。这些文件是针对不同的处理器的,所以对于每一种应用程序支持的处理器需要单独的.cab文件。

安装组件
  这是一个在安装过程中被调用的自定义组件。它运行WinCE应用程序管理器,通过它拷贝和安装正确的.cab文件到设备上。

Setup.ini文件
  向WinCE应用程序管理器描述应用程序信息的初始化文件,在WinCE应用程序管理器安装应用程序的过程中是必不可少的。

WinCE应用程序管理器
  WinCE应用程序管理器位于用户的桌面系统上,用于在Pocket PC设备上安装和卸载应用程序。下图显示应用程序管理器提示用户将要安装示例应用程序在Pocket PC设备上。


图二 从桌面上安装一个Pocket PC应用程序



  .cab文件在Pocket PC上存储安装信息,因此应用程序可以被卸载。用户可以在Pocket PC上直接卸载应用程序,或者从桌面上卸载。用Pocket PC卸载应用程序,用户可以选择应如下图所示的应用程序设置中的删除应用程序。


图三 使用Pocket PC卸载一个应用程序

  就象安装时一样,用户也可以从他们的桌面上卸载应用程序。从控制面板应用程序下的添加删除程序选择要卸载的程序,点击删除按钮。这个过程调用自定义安装组件,由它使WinCE应用程序管理器运行在卸载模式(不需要指定一个Setup.Ini文件)。用户去掉应用程序上的对勾,点击OK去卸载Pocket PC上的应用程序。


图四 从桌面系统上卸载一个PocketPc程序



  开发安装程序的目标是用最小的工作量生成一个.msi文件(如果可能的话,点一下鼠标)。首先让我们看一下开发安装程序过程所涉及的各部分:

  • BuildCab.bat通过运行cab向导启动安装过程
  • 信息文件(.inf)向cab向导提供应用程序描述
  • cab向导根据 .inf 文件所指出的处理器类型生成不同的.cab文件
  • .cab文件,一个自定义安装组件和一个Setup.ini文件被打包成一个.msi文件

下面的图表说明与安装开发过程相关的各部分,接下来是每个部分的描述信息。


图五 与安装开发过程的相关部分

BuildCab.bat
  通过运行Cab向导工具生成特定处理器的.cab文件。当你从生成菜单上选择生成cab文件时,Visual Studio生成一个模板BuildCab.Bat文件。让Microsoft? Visual Studio?生成这个文件,然后拷贝它到一个不同的路径,然后做一些更改是一个好办法。很有可能,仅有的改变是为.cab和log文件指定一个新的路径。示例中的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向导指定了安装设置和应用程序文件。如buildcab.bat文件,当生成cab文件被选择时,Visual Studio生成一个模板.inf文件。你应该首先用Visual Studio生成这个文件,然后拷贝到另外的路径去做一些更改。这个文件通常需要很小的修改;通常修改Provider的名称就可以了。
  Visual Studio生成一个.inf文件包含对vsd_setup.dll的引用。这个dll是用于版本检查以及假如Pocket PC没有正确的安装.Net精简板,报告这个信息。把它包含在你的应用程序中是一个好注意,但为了更清晰,我们把它从示例代码中移除了。
  例子程序中的.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向导
  Cab向导(cabwiz.exe)生成.cab文件,该文件可以被安装在不同的Pocket PC设备上。一个.inf文件作为命令行的第一个参数传递,用于向向导描述应用程序。其它可选参数为目的路径,错误日志文件,和CPU类型。你可以访问You can visit Microsoft Windows CE .NET: CAB Wizard Syntax获取更多的信息。

安装程序组件
  自定义安装组件通过处理AfterInstall和AferUnInstall事件以及运行WinCE应用程序管理器实现部署过程自动化。WinCE应用程序管理器的路径存储在注册表HKLM\software\Microsoft\Windows\CurrentVersion\App Paths\CEAppMgr.exe 健值下。下面是 AfterInstall和AferUnInstall 事件的代码:

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文件用于在 WinCE 应用程序管理器向Pocket PC设备部署应用程序时,描述应用程序信息。下面所示的是Setup.ini的例子。你应该在你的应用程序中设置Version,Description和CabFiles属性。你可以访问Microsoft Windows CE 3.0: Creating an .ini File for the Application Manager 去获取更多的关于.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 app, customer installer, 和 setup)
  • 把自定义的安装组件加入安装过程的安装和卸载自定义动作中
  • 用一个预生成事件去调用BuildCab.bat文件去生成.cab文件
  • 指定项目的依赖性以使项目按正确的顺序生成
  • 用配置管理器设置生成Pocket PC程序的Debug配置和Release配置

  下面的部分更加详细的描述了C#和VB.Net例子解决方案。C#解决方案点一下鼠标就生成所有的项目(Pocket PC应用程序,自定义安装组件和.msi文件)。VB.Net版本需要更多步骤,由于VB.Net缺少这两个属性:

  1. 一个解决方案不能包括不同平台的VB.Net项目(Pocket PC应用程序不能和自定义安装组件在同一个解决方案中)
  2. 预生成和后生成命令事件在任何VB.Net工程中都是不支持的。
    VB.Net方案仍就可以实现自动化的,只是比不上C#版本便捷而已。

解决方案和项目
  C#解决方案包含三个项目:PocketPC App, Custom Installer 和 Setup。PocketPC App项目是一个基于Pocket PC的智能设备应用程序。Custom Installer项目是一个自定义安装组件。安装项目把所有的项目打包成一个.msi文件。下面显示的是C#解决方案。


图六 包含 PocketPC App, Custom Installer 和 Setup 项目

  VB.Net需要两个解决方案。第一个包括智能设备项目PocketApp。第二个解决方案生成一个.msi文件,包括CustomInstaller, Pre-Build 和 Setup项目。CustomInstaller和Setup项目与C#中的项目相同,预生成项目是一个C++ Makefile项目;预生成项目并不包括任何C++代码,仅仅用于指定一个预编译事件。VB解决方案如下图。


图七 包含Pocket PC, installer component, pre-build and setup projects 的 VB.Net解决方案

PocketApp项目
  PocketApp是一个简单的智能设备项目,"Hello World"应用程序;一个PocketPC简单程序。BuildCab.bat和PocketApp_PPC.inf文件用于生成.cab文件,Setup.ini文件用于部署应用程序。
文件app.ico是一个应用程序图标文件,显示在Pocket PC的程序工作组中。下面显示的是在C#和VB.Net中指定应用程序图标。


图八 在C#中指定应用程序图标


图九 在VB.Net中指定应用程序图标


图十 显示在Pocket PC应用程序组中的图标

CustomInstaller项目
  这个组件运行WinCE应用程序管理器,让其部署.cab文件到Pocket PC设备上。C#和VB.Net的代码已经早在上文中说明了。

Setup项目
  安装项目生成一个.msi文件包括特定处理器的.cab文件,CustomerInstaller安装组件和setup.ini文件。CustomerInstaller组件添加进来作为Install和UnInstall自定义动作的响应,如下图所示


图十一 添加Install和UnInstall自定义动作的响应

预生成事件
  在PocketApp项目生成后,你需要运行BuildCab.bat生成.cab文件。Visual Studio不允许你为C#智能设备项目指定生成后命令事件。所以我们最好为CustomerInstaller项目指定一个预生成命令事件。


图十二 用一个预生成命令事件去在C#中生成.cab文件

  Visual Studio不允许VB.Net项目有任何生成事件,所以我们用一个C++ Makefile工程去定义预生成事件,如下图所示。


图十三 用一个C++预生成事件作为VB.Net的解决方法

项目依赖
  由于解决方案包含许多工程,所以设置正确的生成顺序是很重要的。对于C#,生成顺序设置为PocketApp,CustomeInstaller 和 Setup,如下图所示。


图十四 为C#解决方案设置生成顺序

  VB.Net版本包含有两个解决方案;PocketApp解决方案应首先生成,接下来是PocketPCSetup解决方按。Setup解决方案的生成顺序如下图所示。


图十五 指定VB.Net解决方案的生成顺序

配置管理器
  配置管理器用于生成Pocket PC项目在Debug模式和所有的程序在Release模式。就是说,仅为调试应用程序Pocket PC应用程序,你不用经历整个生成过程。C#版本的配置图示如下。
这个配置在VB.Net中不需要,因为其中的一个解决方案是对于Pocket PC的,另外一个解决方案用于生成.msi文件。


图十六 仅生成Pocket PC项目在Debug模式


图十七 生成所有的项目于Release模式

安装和生成示例解决方案
  下面是安装和生成示例解决方案的注意点:

  • 运行PocketPC部署程序Sample.msi文件,安装C#和VB.Net到你的系统中。指向Visual Studio解决方案文件的链结添加在开始菜单中的PocketPC Deploy Sample组下面。
  • 在BuildCab.bat和PocketApp_PPC.inf文件中的硬编码被更新以与你的系统匹配(例子安装文件夹和Visual Studio的路径)。你应该多检查这些文件的路径信息,如果你生成示例程序的时候遇到困难。
  • 选择Release模式生成所有的项目(Debug模式只生成Pocket PC应用程序)。
  • .msi文件命名为PocketApp Setup.msi,在Setup\Release文件夹下创建。
下载本文示例代码
阅读(1423) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~