可以设定虚拟目录的更多属性,如身份验证方式、默认文档等,还可以进行更有力的异常处理。IIS虚拟目录的属性可以参考MSDN IIsWebVirtualDir。
主要内容:
1、介绍System.DirectoryServices.DirectoryEntry
2、如何使用DirectoryEntry来进行虚拟目录的管理
本文相关代码可以发邮件到libiyang@163.com
获取服务器foo上的“默认网站”的节点对象:
如何使用DirectoryEntry来实现IIS虚拟目录的管理
1、创建虚拟目录:
创建虚拟目录的经过以下步骤:
1)获取该虚拟目录的上级目录的DirectoryEntry对象rootEntry;
2)通过rootEntry的DirectoryEntry::Childrens.Add来添加该虚拟目录;
创建虚拟目录的代码如下:
2、删除虚拟目录:
删除虚拟目录比较简单,只需调用虚拟目录的父节点的DirectoryEntry对象的Delete操作就可以了,需要注意的是Delete对象需要两个参数:子节点的Alias和子节点的类型(虚拟目录节点的类型为IIsWebVirtualDir)。
3、判断虚拟目录是否存在:
通过调用父节点的DirectoryEntry对象的DirectoryEntry::Children.Find来查找子结点是否存在,但非常奇怪的当子节点不存在的时候会抛出异常,我更期望的是返回子节点的null引用。
好了,现在Asp.net网站ClickOnce自动部署的第一个问题就解决了。自动部署程序只要把安装目标目录中asp.net网站对应的文件夹设定为虚拟目录就可以了。
主要内容:
1、介绍System.DirectoryServices.DirectoryEntry
2、如何使用DirectoryEntry来进行虚拟目录的管理
本文相关代码可以发邮件到libiyang@163.com
介绍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);
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);
DirecotryEntry entry = new DirectoryEntry("WinNT://foo", user, password);
3)连接IIS服务器
获取本机的“默认网站”的节点对象:
1 // 获取本机的“默认网站”的节点对象
2 DirectoryEntry entry = new DirectoryEntry("IIS://localhost/w3svc/1/ROOT");
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来创建虚拟目录,只能在该虚拟目录建立了以后,才能设置物理目录等属性。DirectoryEntry entry = rootEntry.Children.Add(this.m_strAlias, "IIsWebVirtualDir");
创建虚拟目录的代码如下:
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 /// 创建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 }
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 }
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 }
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网站对应的文件夹设定为虚拟目录就可以了。