要成功移动Prism应用到生产中,需要对部署计划为应用程序的设计过程的一部分。本章介绍了注意事项和你需要采取的准备以部署应用程序,以及你要在用户手中获得部署程序所需要采取的行动。
Silverlight和WPF有两个不同的承载环境,所以部署考虑的内容就不同了,这依赖于是否你在构建一个Silverlight Prism应用程序还是一个WPF Prism应用程序。
部署Silverlight Prism应用程序
Silverlight应用程序通过Http请求昨晚XAP文件从浏览器被分发。XAP文件其实仅仅是一个.zip文件,有一个不同的预期的内容的文件名称。一个XAP文件包含着一系列的程序集,一个描述应用程序包的XAML文件,和应用程序可能会用到的额外的资源文件。XAP文件通过一个嵌在Web页面的SilverLight插件被下载。在Silverlight插件被下载下来之后,它会激活应用程序并在web页面中运行内容。
甚至假如你计划在浏览器外运行你的Silverlight应用程序,用户也将会首先需要在浏览器中通过承载页面获取应用程序;在这之后,用户可以选择性的安装浏览器外应用程序。结果是,基于Prism的Silverlight应用程序的部署将很有可能作为从一个Web服务器上下载XAP文件的主要地方因此承载业可以下载并运行她们。
将Prism模块打包成XAP文件
就像在第4章中讨论的,你可以将你的模块通过多种方式打包,包括即那个多个模块作为一个XAP文件或者一个单独的XAP文件作为一个单独模块的容器。打包方式的决定取决于多个模块是否需要被同时下载由于他们之间的依赖关系或者应用程序的使用情况,或者模块生命周期内在逻辑上是独立的和分离的。将每个模块打包到自己的XAP文件中科院从部署前景和维护中相对的清晰,因为每个XAP文件成为了一个单独的部署单元,每个模块的XAP文件可以单独的版本化,并且可以通过简单的改变以下模块目录来从应用程序中添加或者移除。
作为一个例子,考虑Stock Trader Reference Implementation (Stock Trader RI )项目的架构。它由Shell和四个模块组成,四个模块:Position,watch,market,和news.因为应用程序被设计为所有的这些功能在应用程序启动时被“点亮”,所有的Stcok Trader RI 的模块是被静态添加的。Stock Trader RI shell应用程项目将所有的模块的程序集作为类库进行引用,并且这些模块在应用程序启动过程中通过启动引导程序中的ModuleCatalog.AddModule方法被加载。在这种情况下,从Staock Rader RI.Silverlight shell应用程序项目编译的结果中只有一个XAP文件,并且它包含了Shell,四个模块以及下图中所示的共享的基础类库。如果你正在部署StockTraderRI应用程序,你只需仅仅将那个XAP文件放到Web 服务中国并且并设置你的Silverlight插件在网页托管对象标记的源参数标签指向XAP文件(通常在你的站点的一个\ClientBin 子文件夹中,使用一个ASP.NET Web 应用程序承载项目模板)。
![](https://i-blog.csdnimg.cn/blog_migrate/5b319f036cdbbcfdeacf11a68de33eb1.png)
另外,如果Stock Trader RI 的模块就它们需要被加载时而言它们是松耦合的,它们可以被开发为Silverlight 应用程序项目以使得它们可以被生成到单的XAP文件中。如果你那样做了,部署结构将看起来更像下面的插图。在你将模块打散到它们各自的XAP文件中后,如果合适的化,基于应用程序的功能,你可以有选择的延迟加载一些模块。通常,你需要使用一个打包的ModuleCatalog.xaml文件来决定那些模块是需要被组合的,它们依赖的是什么,以及他妈的加载特点是什么(按需加载或者不按需加载)。
注意下图因为shell和每一个模块都对作为共享类库的基础设施程序集有一个引用,如果您保留默认设置这些引用,你最终会与库中的每个单独的XAP文件的单独副本,这增加了应用程序的不必要的下载大小和带宽利用率。
![](https://i-blog.csdnimg.cn/blog_migrate/eed47bf7cf6b532abd0d85c2066dedaa.png)
缩减模块XAP文件下载大小
为了解决在一个Prism 应用程序中的国歌模块XAP文件中对共享应用程序类库的副本的问题,你有几个选择。第一个就是在应用程序的Shell 的XAP文件中包含这个共享类库,它将在你添加这个引用是作为默认选项。然后然每个也使用了这个引用的模块的引用中设置Copy Local属性的值为false。这样就会使得这个引用程序集不被包含到模块的编译的XAP文件中。然而,在运行时,应用程序的Shell 的XAP文件提供的共享类库可以被其他模块可用。
第二种方式就是利用Silverlight应用程序的缓存。为了使用这个功能,将Silverlight的应用程序属性中的
Reduce XAP size by using application library caching 勾选框勾选。当你这样做时,任何引用程序的正确的元数据文件的计划将不会被包含到XAP文件中;相反,它们将会被放置到一个单独的.zip文件中,并且这个.zip文件将会被XAP文件的ApplicationManifest.xaml文件作为一个额外的部分引用。被标记的Silverlight Prism类库二进制拥有被要求的元数据文件项从Silverlight SDK和Silverlight Toolkit中一样使用这些功能。利用你自己的共享程序集的这个功能,你需要提供一个元数据文件,就是MSDN上描述的"
How to: Use Application Library Caching"。
为Silverlight应用程序准备Web Server
Silverlight应用程序可以被大多数的Web服务器承载,例如,IIS或者Apache,然而,大多数的Web服务器通常是配置性的服务少数的众所周知的文件名后缀,为了是你的Silverlight应用程序从你的Web 服务器取得服务,你毕业允许下表中的MIME类型被服务。
后缀 | MIME 类型 |
---|---|
.xaml | application/xaml+xml |
.xap | application/x-silverlight-app |
部署应用程序
为了部署一个Silverlight应用程序以及模块远程的被加载,Web 服务器上XAP文件必须可以被访问,这里有几种方法来达到这一点:
- 你可以手动的将所有的XAP文件拷贝到Web服务器上。
- 你可以将Silverlight XAP文件包含的一个Web 项目或者Web占点中并从Visual Studio中发布。使用一个Web 应用程序项目做这一点时,这个项目需要作为创建XAP文件的项目作为解决方案的一部分。然后将这个Silverlight 项目们添加到这个Web 项目设置中的Silverlight Applications 页。就像下图所示,来自被包含的Silverlight 项目的拷贝将会被放到发布站点的一个\ClientBin子文件夹中,这些文件在每次你生成项目的时候被保持同步。
![](https://i-blog.csdnimg.cn/blog_migrate/707933b9c426f8709ad8d518de5b5a02.png)
注意:
为了避免交叉域名引起的问题,远程的模块的XAP文件应该被放到相同的域中作为主程序;当你这样部署后,ModuleCatalog的Ref属性应该为一个指向Web服务器上的XAP文件的URI文件。
除了在承载的Web站点中发布和定位XAP文件,承载Web 页面需要在它的对象标记源参数中引用应用程序的XAP文件。因为承载页码应该是同一个Web站点的一部分,出于交叉域名原因它是XAP文件放置的地方,在承载页码中的指定的路径应该是一个相对的路径。
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%"> <param name="source" value="ClientBin/ModularityWithUnity.Silverlight.xap"/> ... </object> |
部署WPF Prism 应用程序
一个WPF Prism应用程序可以有一个可执行程序和若干个额外的DLL组成。主要的可执行程序是Shell应用程序项目。其中一些额外的DLL将会是应用程序的模块。它们可能是被Shell和应用程序的模块共享的程序集额外DLL。另外,你可能会有一系列的资源或者内容文件将会一起在部署的应用程序中。
为了部署一个WPF Prism 应用程序,你有三个选择:
- “XCopy 部署”
- ClickOnce 部署
- Windows Install 部署
通常情况下,部署一个更加自动化的手段是需要的,以确保得到的东西放置在正确的位置,用户可以方便地访问运行该应用程序。为了方便,你可以选择使用的ClickOnce或Windows安装程序(.msi文件),这取决于应用程序有什么额外的安装要求存在。
是否使用的ClickOnce或Windows Installer的决定常常被误解。ClickOnce是不打算成为万能的部署技术。它的目的是为那些需要对其他安装在客户端计算机上的应用程序低影响。如果你的应用程序在其被安装时需要做一个计算机范围的更改,例如安装驱动,与其他应用程序集成,安装服务和该走的只是运行可执行文件范围以外的其他事情,ClickOnce可能不是一个合适的部署选择。然而,如果你只是一个在客户端计算机上的轻量级的安装并且你想要利用网络部署和更新WPF应用程序的优势,ClickOnce 可能是一个不错的选择。
为了给你的应用程序创建一个Windows Installer 安装包(.msi 文件),你有许多的选择,包括Visual Studio 安装项目,Windows Installer XML(WiX) 项目,或者一系列的第三方的安装器创建产品。
使用ClickOnce部署WPF Prism 应用程序
ClickOnce是一个WPF或者WinFrom部署机制,自从 2.0版本以来它成了.NET Framework的一部分。ClickOnce 使得一个WPF应用程序可以通过网络从部署服务哪里自动的部署和更新。WPF Prism应用程序可以使用ClickOnce 来获取Shell,模块,和任何依赖性来部署到客户端机器中。Prism 应用程序的主要挑战就是Visual Studio 为Click Once 发布程序的过程并没有自动的将动态加载模块包括在一个发布的应用程序内。
使用Click Once 发布一个WPF 应用程序过程一共有两步。首先,你必须从Visual Studio 发布应用程序,然后你可以将它部署到客户端计算机。发布应用程序产生两个清单(一个部署清单和一个应用程序清单),并且将应用程序文件拷贝到发布路径下。那个发布文件夹可以被然后移动到另一个服务中,这个服务可能不允许开发者计算机直接访问来使得发布的应用程序可以从一个已知的位置和URL从客户端来访问。部署一个应用程序到客户端计算机仅仅需要提供一个可以导航到的URL或者连接,这个URL指向了发布的部署服务器上的部署清单。当那个URL在浏览器中北加载时,客户端计算机上的Click Once 下载了这个清单以及清单中指定的文件。 当文件被下载并在用户配置文件存储后,ClickOnce 启动应用程序。如果后来更新发布到了部署服务器,ClickOnce可以自动的检测这些更新,下载,并应用它们,或者可以设置,允许你来按需或者在程序启动后在后台来检查和应用它们。
当你发布一个WPF Prism 应用程序时,其拥有动态加载的模块,Shell工程将通常不会引用到动态加载的模块。结果就是,发布的Click Once应用程序清单也不包含这些模块文件,并且如果你使用ClickOnce来部署应用程序,客户端计算机也将不会获取这些模块文件。为了解决这点,你必须修改应用程序清单来包含这些没有被shell工程引用到的模块文件。
ClickOnce发布过程
你可以从Visual Studio 2010中使用一个名为Manifest Generating and Editing tool(Mage)的.NET Framework SDK工具或者一个使用了ClickOnce 发布API的自定义工具来发布ClickOnce 应用程序。然而,Visual Studio 可能不能被在服务器端管理ClickOnce 部署的IT管理员获得或者期望的。Mage 是专门为解决最常见的ClickOnce管理任务而设计的;它是一个轻量级的.NET Framework 窗体应用程序,可以将其给予管理员。然而,Mage要求太多的细节步骤,以正确的顺序执行,来成功的完成常见任务例如修改一个在应用程序清单中列出的应用程序。为了使得这些任务更简单,需要一个自定义的工具。
Manifest Manager Utility 样例工具展示了如何使用Click Once 发布API 用一种简单的方式来管理部署和应用程序清单。这个工具用于在一个用户界面中更新应用程序清单文件列表和部署清单设置并且它的使用在本章中后面的章节描述了初始部署和更新Prism应用程序。Manifest Manager Utility 使用
Microsoft.Build.Tasks.Deployment 命名空间中暴露的API对一个ClickOnce 部署进行加载,操纵,和保存修改的清单文件。你可以从您可以从Prism 社区网站Codeplex上的
http://compositewpf.codeplex.com/releases/view/14771下载Manifest Manager Utility。欲了解参与发布和更新使用动态模块加载一个WPF Prism 应用的具体步骤,请参见
WPF Prism Deployment Hands-On Lab: Publishing and Updating with ClickOnce。
下面的插图展示了一个ClickOnce 应用程序发布的典型的结构,基于Visual Studio 生成部署文件夹的方式当你使用Click Once发布应用程序时。它包含了应用程序的跟文件夹,其包含了默认的部署清单(.application 文件)。默认的部署清单通常指向被Visual Studio 生成的最新发布的版本,但是它可以被指向管理员选择的任何版本。根文件夹也包含了Setup.exe启动器,其使你来部署前准备应用程序可能要求的一个安装器的或者在使用Cilck Once 部署应用程序前执行运行程序。然后会有一个应用程序指定的文件的子文件夹,在其下面你可以获得单独的任何你发布的版本。发布版本是一个单独的项目设置和相对于包含组件的各个组件的版本的用于整个部署版本部署清单文件条目。发布版本所使用的ClickOnce来确定何时有可从一个已经安装了ClickOnce应用程序客户端的更新。
![](https://i-blog.csdnimg.cn/blog_migrate/d85a988e8c00e91036dd4a969a7b8fd5.png)
在每一个发布的版本应用程序文件夹下面,你有一个部署清单(.application 文件)的副本,其可以用于部署指定的版本到一个客户端计算机中,或者它可以复制到根文件夹下来使得服务器端会滚到之前的版本。应用程序可执行文件,另外任何部署的类库(例如Prism 模块程序集)和资源文件,将也会在这个文件夹中,并且将会被Visual Studio 在发布时自动的添加一个.deploy文件名扩展。这样做仅仅是将扩展文件映射到发布的Web 服务器上以使得你不必允许下载的.dll,.exe和应用程序是由其他潜在的文件类型无数。
应用程序清单文件也包含在这个文件夹中并且它被部署清单引用。它包含了组成应用程序的每个文件的哈希值以协助变化检测的文件的集合。他也包含了被应用程序允许所要求权限列表,因为ClickOnce的可以根据需要在部分信任的AppDomain启动应用程序。
如果你手动的使用Mage或者一个自定义工具来生成或者更新一个部署应用程序发布,你是不是受限于此文件夹和文件结构。对于任何特定的ClickOnce发布,依赖关系链中包括以下:
- 它包含了一个部署清单,其通过一个基于URL嵌入的代码指向了应用程序清单
- 它包含了一个应用程序清单,其包含了每一个应用程序文件的相对路径。这些文件必须被访者相同的文件夹中或者一个应用程序清单下的子文件夹中。
ClickOnce部署和更新过程
应用程序通过ClickOnce的用户的实际部署几乎总是通过提供URL或超链接到部署服务器上发布的应用程序的部署清单开始。用户可以单击超链接或在浏览器中输入地址,ClickOnce部署过程被调用。清单和应用程序文件下载到客户计算机后,应用程序被启动。有ClickOnce的选项让您在初始部署脱机使用过程中安装应用程序,也可以要求用户每次使用链接到启动应用程序或URL。当您发布应用程序的新版本部署服务器,ClickOnce的可以自动或手动检查更新,并下载和为下一次应用程序启动应用更新。
更多信息
关于如何在Silverlight 程序中使用应用程序类库缓存的更多信息,请参考MSDN上的 "How to: Use Application Library Caching" :
http://msdn.microsoft.com/en-us/library/dd833069(VS.95).aspx
下载 Manifest Manager Utility 从 Codeplex上的Prism 社区占点,在
http://compositewpf.codeplex.com/releases/view/14771.
欲了解参与使用动态模块加载来发布和更新WPF Prism应用程序的具体步骤,请参考
WPF Prism Deployment Hands-On Lab: Publishing and Updating with ClickOnce.