Asp.net网站的ClickOnce自动部署

Asp.net网站的ClickOnce自动部署

前段时间对asp.net网站的自动部署比较感兴趣,自己研究了一阵子,终于有小成。总结了一下,我打算写一系列关于Asp.net网站自动部署的文章,主要内容包括:

1、Web虚拟目录的配置
2、SqlServer数据库的配置
3、配置文件的修改和加密
4、WindowsNT用户和Active Directory用户的配置

有必要说明的是,对于简单的Web的自动部署可以使用.Net自带的Web安装项目来做自动部署程序,只需要创建自己的System.Configuration.Installer的派生类就可以了,这方面的文章可以看看MSDN的Deployment Workthrough,里面介绍了包括一些简单WinForm、WebForm和数据库自动部署的方法。

但是对于复杂的工程(像电子政务平台这样的有多个Solution项目构成,并且在部署的时候需要进行很多的配置工作)来说不适用了,除了方便拷贝文件以外没有其他的便利了。有兴趣的看官可以自己去试一下,看看如何用.Net自带的WebSetup来制作满足一下需求的自动部署安装包:
1)该应用系统由多个Solution组成,并且每个Solution中可能有多个UI。
2)每个UI下都有很多未包含进工程的文件,如图片、帮助文档、配置文件等
3)最后打包成一个安装包

相信我,极其痛苦。听说vs2005里面增加了clickonce的自动部署功能,没有接触过,如果有了解的看官,请不吝赐教,wkai_chen(这是@)hnair.com。

 

第一步先讲虚拟目录的配置,虚拟目录的配置简单来说就是创建虚拟目录。用手工的方式实现非常简单,直接设定“Web sharing”就可以了,让我们看看怎么通过编程的方式实现,本文将介绍两种创建虚拟目录的方法:

1、通过调用iisvdir.vbs,
2、通过System.DirectoryServices.DirectoryEntry。

如果看官有其他的方法,欢迎讨论chwkai@gmail.com

为了方便描述,我写了两个虚拟目录操作类,简单的封装了iisvdir.vbs和System.DirectoryServices.DirectoryEntry管理虚拟目录的方法,结构如下所示:


Server为iis服务器的ip或机器名,User和Password为该服务器的管理员用户名和密码,Alias为虚拟目录的名称,VirtualRoot为虚拟目录所在根目录的名称(如下图),PhysicalPath为该虚拟目录相应的物理路径。如果想进一步了解IIS虚拟目录的属性,可以参考MSDN IIsWebVirtualDir


通过调用iisvdir.vbs创建虚拟目录

看官可以参考一下MSDN的相关资料:
Creating Web Virtual Directories Using Iisvdir.vbs
Deleting Web Virtual Directories Using Iisvdir.vbs <script language="Javascript" type="text/javascript"> if(typeof(IsPrinterFriendly) != "undefined") { var o = document.getElementById("EBABAAAAAAAAACA"); if(o != null) o.innerHTML = "[/WindowsServer/en/Library/e350ca8d-644a-4236-8f3d-57bb79afbd441033.mspx]"; } </script>
Listing Web Virtual Directories Using Iisvdir.vbs <script language="Javascript" type="text/javascript"> if(typeof(IsPrinterFriendly) != "undefined") { var o = document.getElementById("EBAAAAAAAAAAACA"); if(o != null) o.innerHTML = "[/WindowsServer/en/Library/e26bdfe1-a885-4261-89c3-c45fb6d4405e1033.mspx]"; } </script> .

仔细看还会发现, IIS管理器也是通过调用iisvdir.vbs来实现虚拟目录的创建和删除的。我们可以通过命令行的方式来执行iisvdir.vbs脚本,
1)创建虚拟目录:

cscript c:/windows/system32/iisvdir.vbs [/s server] [/u username /p password] /create [virtualRoot] Alias PhysicalPath


2)删除虚拟目录:

1cscript c:/windows/system32/iisvdir.vbs [/s server] [/u username /p password] /delete [virtualRoot]/Alias


3)查看指定虚拟目录下的全部子目录:

1cscript c:/windows/system32/iisvdir.vbs [/s server] [/u username /p password] /query virtualRoot


通过封装这三个操作,可以实现iis虚拟目录的创建、删除和判断是否存在:
1)创建虚拟目录:

 1 /// <summary>
 2         /// 创建iis虚拟目录
 3         /// </summary>
 4         /// <exception cref="CreateIIsDirectory.DirectoryException">虚拟目录操作异常</exception>
 5         public override void CreateDirectory()
 6         {
 7             // 已不覆盖的方式创建虚拟目录,当虚拟目录存在时抛出异常
 8             this.CreateDirectory(false);
 9         }
10 
11         /// <summary>
12         /// 创建iis虚拟目录
13         /// </summary>
14         /// <param name="bReplace">是否覆盖掉原有的虚拟目录</param>
15         /// <exception cref="CreateIIsDirectory.DirectoryException">虚拟目录操作异常</exception>
16         public override void CreateDirectory(bool bReplace)
17         {
18             // 判断目录是否存在
19             if (this.Exist())
20             {
21                 if (bReplace)
22                 {
23                     // 若允许覆盖则先删除原有的虚拟目录
24                     this.DeleteDirectory();
25                 }
26                 else
27                 {
28                     // 若不允许覆盖直接抛出目录已存在的异常
29                     DirectoryException.Throw("directory already exist");
30                 }
31             }
32 
33             ReturnMessage message = ScriptDirectory.ExecuteScript(
34                 this, ScriptDirectory.CONST_ACTION_CREATE);
35 
36             // 输出message信息供nunit查看
37             Console.WriteLine("return code: " + message.Code);
38             Console.WriteLine("return message: /n" + message.Message);
39 
40             // 若创建失败抛出虚拟目录操作异常
41             if (message.Code != 0)
42             {
43                 DirectoryException.Throw(message.Message);
44             }
45         }


2)删除虚拟目录:

 1 /// <summary>
 2         /// 删除iis虚拟目录
 3         /// </summary>
 4         /// <exception cref="CreateIIsDirectory.DirectoryException">虚拟目录操作异常</exception>
 5         public override void DeleteDirectory()
 6         {
 7             ReturnMessage message = ScriptDirectory.ExecuteScript(
 8                 this, ScriptDirectory.CONST_ACTION_DELETE);
 9 
10             // 输出message信息供nunit查看
11             Console.WriteLine("return code: " + message.Code);
12             Console.WriteLine("return message: /n" + message.Message);
13 
14             // 若删除失败抛出虚拟目录操作异常
15             if (message.Code != 0)
16             {
17                 DirectoryException.Throw(message.Message);
18             }
19         }


3) 判断虚拟目录是否存在:

 

 1 /// <summary>
 2         /// 判断iis虚拟目录是否存在
 3         /// </summary>
 4         /// <returns>目录是否存在</returns>
 5         public override bool Exist()
 6         {
 7             ReturnMessage message = ScriptDirectory.ExecuteScript(
 8                 this, ScriptDirectory.CONST_ACTION_QUERY);
 9             bool bExist = false;
10 
11             // 输出message信息供nunit查看
12             Console.WriteLine("return code: " + message.Code);
13             Console.WriteLine("return message: /n" + message.Message);
14 
15             // 从返回字符串中判断该虚拟目录是否存在
16             if (message.Code == 0)
17             {
18                 Regex reg = new Regex("/" + this.m_strAlias + @"/s+");
19                 message.Message = message.Message.Substring(
20                     message.Message.IndexOf("/"));
21 
22                 bExist = reg.IsMatch(message.Message);
23             }
24 
25             return bExist;
26         }


ScriptDirectory.ExecuteScript函数封装了iisvdir.vbs的调用和参数的组合,代码比较长,大家可以在/Files/chwkai/CreateIIsDirectory.rar下载到本文所讨论的代码。

orz,明天还有场球赛,睡觉了。下次的文章将继续写到,如何用System.DirectoryServices.DirectoryEntry来创建IIS虚拟目录,相对于iisvdir.vbs,这种方式更加灵活,并且具有更多的功能,如设定虚拟目录属性等。

在上一篇的Asp.net网站的ClickOnce自动部署(2)-虚拟目录的配置 里面,我介绍了如何通过封装iisvdir.vbs的调用来实现iis虚拟目录的配置,今天继续介绍如何使用System.DirectoryServices.DirectoryEntry来实现iis虚拟目录的管理,供初学者参考。相对于调用iisvdir.vbs的脚本,后者可以设定虚拟目录的更多属性,如身份验证方式、默认文档等,还可以进行更有力的异常处理。IIS虚拟目录的属性可以参考MSDN IIsWebVirtualDir

主要内容:
1、介绍System.DirectoryServices.DirectoryEntry
2、如何使用DirectoryEntry来进行虚拟目录的管理

本文相关代码可以从/Files/chwkai/CreateIIsDirectory.rar下载。

 


 

介绍System.DirectoryServices.DirectoryEntry
虽然在MSDN中的说法是"封装 Active Directory 层次结构中的节点或对象",但是通过DirectoryEntry,我们可以连接ActiveDirectory服务器来获取AD上的信息,用来连接WindowNT服务器来管理服务器上的用户,甚至还可以用来管理IIS。

1)连接ActiveDirectory服务器:

// 获取AD服务器foo.com的连接
DirectoryEntry entry = new DirectoryEntry("LDAP://foo.com/DC=foo, DC=com", user, password);

2)连接WinNT服务器:

// 获取NT服务器foo的连接
DirecotryEntry entry = new DirectoryEntry("WinNT://foo", user, password);

3)连接IIS服务器
获取本机的“默认网站”的节点对象:

1 // 获取本机的“默认网站”的节点对象
2 DirectoryEntry entry = new DirectoryEntry("IIS://localhost/w3svc/1/ROOT");


获取服务器foo上的“默认网站”的节点对象:

DirectoryEntry entry = new DirectoryEntry("IIS://foo/w3svc/1/ROOT", user, password);

通过DirectoryEntry,我们可以很方便的管理这些服务器上的节点。


如何使用DirectoryEntry来实现IIS虚拟目录的管理

1、创建虚拟目录:
创建虚拟目录的经过以下步骤:
1)获取该虚拟目录的上级目录的DirectoryEntry对象rootEntry;
2)通过rootEntry的DirectoryEntry::Childrens.Add来添加该虚拟目录;

// 创建虚拟目录
                DirectoryEntry entry = rootEntry.Children.Add(this.m_strAlias, "IIsWebVirtualDir");

3)更新该虚拟目录的属性,如更新身份验证模式,访问权限和所对应的物理目录等。需要注意的是,使用DirectoryEntry来创建虚拟目录,只能在该虚拟目录建立了以后,才能设置物理目录等属性。

创建虚拟目录的代码如下:

 1 /// <summary>
 2         /// 创建iis虚拟目录
 3         /// </summary>
 4         /// <exception cref="CreateIIsDirectory.DirectoryException">虚拟目录操作异常</exception>
 5         public override void CreateDirectory()
 6         {
 7             // 已不覆盖的方式创建虚拟目录,当虚拟目录存在时抛出异常
 8             this.CreateDirectory(false);
 9         }
10 
11         /// <summary>
12         /// 创建iis虚拟目录
13         /// </summary>
14         /// <param name="bReplace">是否覆盖掉原有的虚拟目录</param>
15         /// <exception cref="CreateIIsDirectory.DirectoryException">虚拟目录操作异常</exception>
16         public override void CreateDirectory(bool bReplace)
17         {
18             // 判断目录是否存在
19             if (this.Exist())
20             {
21                 if (bReplace)
22                 {
23                     // 若允许覆盖则先删除原有的虚拟目录
24                     this.DeleteDirectory();
25                 }
26                 else
27                 {
28                     // 若不允许覆盖直接抛出目录已存在的异常
29                     DirectoryException.Throw("directory already exist");
30                 }
31             }
32 
33             try
34             {
35                 // 获取上级目录的DirectoryEntry对象
36                 DirectoryEntry rootEntry = SystemDirectory.GetParentEntry(this);
37                 // 创建虚拟目录
38                 DirectoryEntry entry = rootEntry.Children.Add(this.m_strAlias, "IIsWebVirtualDir");
39                 entry.Invoke("AppCreate"true);
40                 entry.CommitChanges();
41                 rootEntry.CommitChanges();
42 
43                 // 更新虚拟目录属性
44                 SystemDirectory.UpdateEntry(entry, this.Property);
45             }
46             catch (System.Exception ex)
47             {
48                 DirectoryException.Throw(ex.Message);
49             }
50         }

DirectoryEntry的commitChanges方法用于提交DirectoryEntry的操作。line41中的提交了以后,该虚拟目录才能建立,然后在进行更新虚拟目录的属性的操作。若没有commitChanges就进行更新操作,会抛出找不到虚拟目录的异常,有兴趣的朋友可以试试。

2、删除虚拟目录:
删除虚拟目录比较简单,只需调用虚拟目录的父节点的DirectoryEntry对象的Delete操作就可以了,需要注意的是Delete对象需要两个参数:子节点的Alias和子节点的类型(虚拟目录节点的类型为IIsWebVirtualDir)。

 1 /// <summary>
 2         /// 删除iis虚拟目录
 3         /// </summary>
 4         /// <exception cref="CreateIIsDirectory.DirectoryException">虚拟目录操作异常</exception>
 5         public override void DeleteDirectory()
 6         {
 7             // 判断目录是否存在
 8             if (! this.Exist())
 9             {
10                 // 若待删除的虚拟目录不存在,则抛出异常
11                 DirectoryException.Throw("directory does not exist");
12             }
13 
14             try
15             {
16                 // 获取上级目录的DirectoryEntry对象
17                 DirectoryEntry rootEntry = SystemDirectory.GetParentEntry(this);
18                 // 删除参数
19                 object[] objParams = new object[2];;
20                 objParams[0= "IIsWebVirtualDir";
21                 objParams[1= this.m_strAlias;
22                 // 删除虚拟目录
23                 rootEntry.Invoke("Delete", objParams);
24                 rootEntry.CommitChanges();
25             }
26             catch (System.Exception ex)
27             {
28                 DirectoryException.Throw(ex.Message);
29             }
30             
31         }


3、判断虚拟目录是否存在:
通过调用父节点的DirectoryEntry对象的DirectoryEntry::Children.Find来查找子结点是否存在,但非常奇怪的当子节点不存在的时候会抛出异常,我更期望的是返回子节点的null引用。

 1 /// <summary>
 2         /// 判断iis虚拟目录是否存在
 3         /// </summary>
 4         /// <returns>目录是否存在</returns>
 5         public override bool Exist()
 6         {
 7             bool bExist = false;
 8             
 9             try
10             {
11                 DirectoryEntry rootEntry = SystemDirectory.GetParentEntry(this);
12                 DirectoryEntry entry = rootEntry.Children.Find(this.Alias, "IIsWebVirtualDir");
13                 bExist = (entry != null);
14             }
15             catch{}
16 
17             return bExist;
18         }


好了,现在Asp.net网站ClickOnce自动部署的第一个问题就解决了。自动部署程序只要把安装目标目录中asp.net网站对应的文件夹设定为虚拟目录就可以了。

下一篇文章将介绍如何实现sqlserver数据库的自动部署,解决数据库的异地安装问题,并且还会简单介绍如何通过SQLDMO和bcp等工具实现sqlserver数据库的备份和恢复,数据库数据导入和导出。

^_^,最近有点晕,web2.0 、 搜索引擎、代码生成器和内容管理都在搞,过段时间打算写一个如何编写C#代码生成器的的专题,基于o/r mapping和asp.net 2.0的,不知道朋友们是否会喜欢。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值