2005.2.1 欧岩亮
内容介绍
介绍Windows应用程序的配置与部署,和如何将应用程序代码变为产品
课程基础
熟悉Microsoft .NET Framework
了解基本的.NET开发和什么是应用程序集
课程内容
配置——Configuration
配置文件
System.Configuration名称空间
访问注册表
独立存储(Isolated Storage)
部署
部署选项
私有的和共享的应用程序集
Updater Application Block
配置(Configuration)
配置应用程序有4个不同的方法:
配置文件(Config files)
一般不需要具有某些安全性,最好不要在配置文件存储密码,因为它是以明文存在的。如果一定要在配置文件中存储敏感信息,最好使用Hash等加密的方法存密文。
注册表(Registry)
可以在注册表上存储敏感信息,注册表不仅可以存储信息,还可以在注册表项上加上访问控制列表,即ACL,保证某些人的访问权限。还可以在注册表中存储一些不经常改变的信息,例如安装的版本信息等。
独立存储(Isolated storage)
可以存储一些经常变化的信息,例如用户在使用软件的时候,上一次关闭程序时,工具栏的布局位置、程序窗口的位置、大小等。
数据库(Database)
比较灵活,我们呢可以任意构造数据结构。
App.config文件
具有一定Schema的XML文件
appSettings:添加key/value对
IDE在编译时将App.config拷贝到/debug或者/release的目录当中,并将文件名改为appname.exe.config(appname是我们的应用程序名字)
在运行时app.exe.config文件中的配置选项被framework加载。我们可以通过appSettings中的key得到value
自定义配置选项,Custom Configuration Sections。当我们想自定义Schema的时候,framework不能自动解析我们的Schema格式,它只能替我们加载XML的node,只能是我们自己写一个类继承自IConfigurationSectionHandler处理我们的XML。
演示一
配置文件
cs代码中ConfigurationSettings指的是App.config文件,AppSettings属性是负责读取文件里的appSettings节点,它将解析这个节点里的所有add标签后面的所有key/value对,将这些对变成Hash表。
自定义配置选项和IConfigurationSectionHandler
<appSettings>和<add>配置块,具有一定的局限性
可以在.config文件头部建立<configSections>来定义自己的配置块
为每一个自定义的块创建一个<section>并实现相应的handler
创建自己的section并编写XML配置文件
建立一个类实现IConfigurationSectionHandler接口,来解析自定义格式的XML文件
调用Configuration.GetConfig(string SectionName)方法,Framework会调用你实现的IConfigurationSectionHandler.Create()接口
演示二
自定义配置块
下部分的DisplayBeautyTipsSection,Framework不能自动去解析,所以我们需要用下面的代码自己实现解析
使用Config
ConfigurationSettings的GetConfig方法会去驱动Framework把App.config中名称为DisplayBeautyTipsSection节点内容读取到一个XML的Node里面。之后Framework会去自动地调用App.config文件中section标签里对应DisplayBeautyTipsSection名称配置的type类的Create方法。我们这个例子中的Create方法是把XML内容作为对象原样返回。实际运用中,我们可以不返回XML节点,而返回自定义的存储结构,这样我们使用起来就更方便。
注册表
Microsoft .Win32名称空间(这个空间里有访问SystemAPI的方法)
RegistryKey类:CreateSubKey(),GetSubKey(),DeleteSubKey(),GetValue(),等方法
四个主要的键:
Registry.LocalMachine
Registry.CurrentUser
Registry.ClassesRoot
Registry.CurrentConfig
可以在注册表键值上加一个Windows Access Control List(ACL)来控制注册表键的安全性。添加保护权限的时候,它的类在System.Security.Permissions.RegistryPermission…里面定义。
演示三
注册表访问
独立存储(Isolated Storage)
独立存储可以用于存储与用户相关的、经常变化的数据
实际的存储区域、路径
支持漫游的存储(域存储)
<SystemDrive>\Documents and Settings\<user>\Application Data
非漫游的存储路径(本地存储)
<SystemDrive>\Documents and Settings\<user>\Local Settings\Application Data
所有支持串列化(Serializable)的对象都可以通过Isolated Storage Stream存储到相应的磁盘空间上
独立存储的代码
GetStore得到用户独立存储的区域,IsolatedStorageFileStream会在用户存储区域创建独立存储的文件,然后再用IFormatter串列化一些用户信息到文件中。
演示四
独立存储的代码
在应用程序启动的时候,读取用户的状态特性,恢复上次的应用程序运行状态
如果用户是在域中存储,那么就把IsolatedStorageScope的属性设置为Roaming,如果是本地就设置为User。通过反串列化文件内容,得到具体的用户特性。
这里我们的catch不做任何事,吃掉了异常。这是一个反例,因为我们应用程序第一次运行的时候,文件Settings.isf肯定不存在,在打开文件并串列化的时候一定会出现异常,这个异常在这个时候是正常的,因此我们这里吃掉异常。
关闭应用程序的时候,存储应用程序运行状态
这样我们在下次运行应用程序的时候,就会让窗体大小和位置与上次关闭时一致了。
但是如果我们把应用程序拷贝一份,然后运行,窗体会又回到默认位置,这说明拷贝后的应用程序属于两个不同的应用程序集,对于独立存储,.NET会分别对待。
而且在一个C盘非常深的目录下我们能找到Settings.isf这个文件
如果我们把这个文件删除,再运行程序,程序又会回到默认值状态。
部署方案
Xcopy部署
安装部署
Private和Shared的应用程序集
Side-by-side部署
Xcopy部署
Xcopy所有与应用程序相关的文件:.exe的程序集,引用的.dll程序集(除了GAC当中的.dll文件),和配置文件.config文件
对于简单的应用程序来说是个很好的选择,安装时不需要进行很多的配置工作
如果需要将程序集注册到GAC当中,或应用程序需要进行大量配置,这种配置方式不适用
演示五
Xcopy部署
把Debug或Release文件夹下的文件拷贝到新的目录,即可正常运行程序。
安装部署
Setup Project模板,位于Setup and Deployment Projects
打包成.msi文件
创建安装向导
自定义安装步骤
Installer类
在应用程序集当中添加一个Installer类
他会被自定义的安装和部署工程或被InstallUtil.exe在进行安装的过程中被调用
需要将这个类从System.Configuration.Install.Installer派生
重载Install方法
实现自定制的安装代码
Context.Parameters集合中包含了安装时传入的数据或参数信息
演示六
创建Setup工程
ms-help://MS.MSDNQTR.2005JAN.1033/vsintro7/html/vbtskCreatingInstallerForYourApplication.htm
Setup工程默认情况下是不和其他工程一起编译的,它会被跳过,因为它编译的速度比较慢。我们可以设置解决方案的属性来改变。
在Setup工程打上勾,就会和其他项目一起编译了。
建立新快捷方式
只有在开发环境中运行Setup程序,它才会默认的卸载以前安装的程序,重新安装。如果打好包之后直接运行安装包,它会提示是否卸载,还是Repair。
如果想要修改安装的默认路径,需要修改Setup工程的属性。
改为
因为在Application Folder的属性中DefaultLocation默认路径属性与这个设置相关
如果想在安装中得到用户的输入,可以定义一个变量CustomActionData:/ServerName=[EDITA1]。这是EDITA1的用户输入的值会放在ServerName变量里面。
在UserInterface里面定义安装界面
这里Edit1Property的EDITA1是和CustomActionData中的[EDITA1]名称对应的。
添加Installer类,重载Install方法
在Installer类中,我们可以通过访问Context.Parameters字典的"ServerName"来得到用户输入的值。
UpdateConfigFile类,先得到当前应用程序集,得到应用程序的配置文件,读取配置文件,找到配置文件中链接字符串的位置,并且将连接字符串中Server的地方换成用户输入的服务器地址。
私有和共享应用程序集
私有程序集只对该应用程序的可执行代码时可见的,通常位于可执行文件的相同目录下
共享程序集需要具有强命名(Strong Name)并且需要被安装到Global Assembly Cache(GAC)当中
对于共享的强命名程序集来说,你可以安装多个版本的应用程序集,实现side-by-side部署
演示七
私有的和共享的应用程序集
把生成的Northwind.snk复制到我们的工程路径下,然后在需要强签名的项目的AssemblyInfo里面写好snk文件的路径
C:\Windows\assembly的目录里面的程序集是本地计算机里面的公有程序集。编译成功之后,我们可以通过把编译好的应用程序集dll放到C:\Windows\assembly的目录里。
我们可以把不同版本的应用程序集都放在这个目录下,这样在我们应用程序集升级的时候将不会影响老的应用程序。应用程序的强签名是和程序加密没有关系的,它只是生成了一个密钥对,GAC通过签名来检测应用程序是不是同一个公司或者同一个位置来的。
Updater Application Block
“Pull模式”,这种方式可以自动的将位于中心服务器上的应用程序集下载到本地运行
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/updater.asp
总结
.NET具有多种方式来存储配置数据,包括配置文件、注册表和独立存储
可以根据不同的需要进行不同方式的部署,包括Xcopy部署,安装部署等等
可以通过side-by-side的方式来部署应用程序集,在GAC中可以保存多个版本的强命名的程序集
2010.10.13