Net中如何操作IIS

前天在csdn看到有人问如何使用C#操作IIS,很久之前就想写一写这方面的文章,这次正好毕业做完有点时间,我就有空静下心来写这一文章。在写本文前,我首先花了一天的时间写了一操作IIS的类(编译后也可以称之组件),进一步简化了操作,源代码下一篇将全部贴出来,还有一些测试程序,有兴趣的朋友可以到这里下载。

.Net中实际上已经为我们在这方面做得很好了。FCL中提供了不少的类来帮助我们完成这项工作,让我们的开发工作变非常简单和快乐。编程控制IIS实际上很简单,和ASP一样,.Net中需要使用ADSI来操作IIS,但是此时我们不再需要GetObject这个东东了,因为.Net为我们提供了更加强大功能的新东东。

System.DirectoryServices命名空间中包括了些强大的东东--DirectoryEntry,DirectoryEntries,它们为我们提供了访问活动目录的强大功能,在这些类允许我们操作IIS、LDAP、NDS以及WinNT,功能很强大的吧:)

不过我们此处只谈IIS的控制,一般来说,我们操作IIS一般都是对虚拟目录的操作,因此我将此列为主要的内容来讲。

首先我们要搞清楚IIS的层次结构的问题,下面是我从国外找来的一张图,很好的解释了IIS的层次结构:



为了搞清楚IIS的控制语法,我们就必须搞清上图,了解IIS元数据(Metabase)的层次结构。图中的每一个节点称之Key,而每个Key可以包含一个或多个值,这些值就是我们说的属性(properties),IIS元数据中的Key与IIS中的元素是相符的,因此元数据中的属性值的设定是会影响IIS中的设置。这就是我们编程的基本思路和核心。

另外还要了解一下Schema这个概念。它表示IIS中构架的名称,即可以理解IIS元数据中Key的类型,具体点说就是指每个结点的类型。我们知道,IIS中有虚拟目录,普通目录,以及文件这些东东,而这些都属于IIS的元素,区分的他们的标帜就是Schema。比如虚拟目录的Schema就是"IIsVirtualDir",普通目录就是"IIsWebDir"。这样我们添加、删除目录时,IIS就知道我们添加的是虚拟目录还是普通目录。

创建虚拟目录

DirectoryEntry是.Net给我们的一大礼物,他的名字我们就知道他的功能--目录入口。使用过ADSI的人都知道操作IIS,WinNT这些时,我们还需要提供他们的Path,操作IIS时,这个Path的格式为:

IIS://ComputerName/Service/Website/Directory

ComputerName:即操作的服务器的名字,可以是名字也可以是IP,经常用的就是localhost
Service:即操作的服务器,IIS中有Web,也有FTP,还有SMTP这些服务,我们主要是操作IIS的Web功能,因此此处就是"W3SVC",如果是FTP则应是"MSFTPSVC"
WebSite:一个IIS服务中可以包括很多的站点,这个就用于设置操作的站点。他的值是一个数字,默认是1,表示缺省站点,如果有其它,则从1开始依次类推。
Directory:不用说,即操作的目录名称,一个站点一般顶层目录为"ROOT",其它目录则是他的孩子(Child)。
首先我们获取一个站点的顶层目录(根目录):

DirectoryEntry rootfolder = new DirectoryEntry("IIS://localhost/W3SVC/1/ROOT");

如果我们创建这个对象是没有发生异常,则表示这个目录是真实存在的。

下面我们来添加新的虚拟目录,比如我们要加的是"Aspcn":

DirectoryEntry newVirDir = rootfolder.Children.Add("Aspcn","IIsWebVirtualDir");
newVirDir.Invoke("AppCreate",true);
newVirDir.CommitChanges();
rootfolder.CommitChanges();
 

创建目录的思路很简单,即在根目录的子集(rootfolder.Children)中再添加一条记录,这里使用的是DirectoryEntries类中的Add方法,它返回的是一个DirectoryEntry,表示新加入的目录,第一个参数是虚拟目录的名字,第二个则是Schema的类名以表明我们加入的目录类型。然后再使用DirectoryEntry的Invoke方法,调用ADSI中的"AppCreate"方法将目录真正创建(似乎不走这一步也可以创建目录成功,但是为了保险起见,大家还是用吧),最后便是依次调用新、根目录的CommitChanges方法,确认此次操作。

在创建新目录时,我们也可以同时给这个目录的属性赋值,但是我的实战经验告诉我,最好不要这样做,如果创建时就赋值,将有很多属性不能赋值成功,比如重要的表示真实目录的Path属性。因此飞刀建议大家最好是先创建目录,然后再赋值,即更新目录信息。

更新虚拟目录

相信大家对IIS都比较熟悉,了解IIS中一些重要的设置,如可读(AccessRead)、可写(AccessWrite)、可执行(AccessExecute)等。这些都可通过对DirectoryEntry的Properties属性集合的赋值来实现。赋值可以通过两种方式来完成:

第一种是调用Properties集合的Add方法,如:

dir.Properties["AccessRead"].Add(true);

第二种是对第一个索引值赋值:

dir.Properties["AccessRead"][0] = true;

这两种方法都是可行的。具体是要看你的喜好了。

在进行赋值之前我们还是要确定要要赋值的目标吧:)这里我们使用DirectoryEntries类的Find方法,如:

DirectoryEntry de = rootfolder.Children.Find("Aspcn","IIsVirtualDir");

找到了,我们就可以赋值了。赋值时一定要好好看看啊,虚拟目录的属性值可以超多,一查一大堆。。:(太多了,飞刀我也不重复了,大家去微软的站点上查:)

比较常用的有:AccessRead,AccessWrite,AccessExecute,AccessScript,DefaultDoc,EnableDefaultDoc,Path

删除虚拟目录

删除虚拟目录的方法也很简单,就是找到你要删除的虚拟目录,然后调用AppDelete方法。

DirectoryEntry de = rootfolder.Children.Find("Aspcn","IIsVirtualDir");
de.Invoke("AppDelete",true);
rootfolder.CommitChanges();
 

还有一种方法,就是调用Root目录的Delete方法。

object[] paras = new object[2];
paras[0] = "IIsWebVirtualDir"; //表示操作的是虚拟目录
paras[1] = "Aspcn";
rootfolder.Invoke("Delete",paras);
rootfolder.CommitChanges();

喜欢哪一种就看编程习惯了:))

关于我写的类

我写的那个类库,将这些进一步简化了。只需要调用一下Connect()方法,就可直接操作Create,Delete方法了,程序可以进一步简化,并且支持批量操作。


张叶 已经将该联络单转发了给下列人员: 林飞,林嘉成,彭贇,邱匡波,曾颖焙.
2004-11-3 9:55:23 192.168.2.17

★第14★楼 提示信息(转发联络单) ★引用 ★删除



张叶 已经将该联络单转发了给下列人员: 谢鹍.
2004-7-17 10:34:14 192.168.2.17

★第13★楼 在应用程序级别以外使用注册为 allowDefinition=’MachineToApplicati ★引用 ★删除



张叶 在应用程序级别以外使用注册为 allowDefinition=’MachineToApplication’ 的节是错误的。导致该错误的原因可能是在 IIS 中没有将虚拟目录作为应用程序进行配置。

2004-7-16 16:51:55 192.168.2.17

★第12★楼 vb5 ★引用 ★删除



张叶
Public Function ExecuteProcess(ByVal cmd As String)
Dim startInfo As New ProcessStartInfo(cmd)
Dim proc As Process = Process.Start(startInfo)
proc.WaitForExit()
End Function

Public Function GrantDBAccessNT(ByVal connectionString As String, ByVal account As String)
Dim cn As New SqlConnection(connectionString)
cn.Open()

Dim cmd As New SqlCommand
cmd.Connection = cn
cmd.CommandText = "exec sp_grantlogin N’" + account + "’"
cmd.ExecuteNonQuery()
cmd.CommandText = "exec sp_defaultdb N’" + account + "’, N’master’"
cmd.ExecuteNonQuery()
Try
cmd.CommandText = "exec sp_grantdbaccess N’" + account + "’"
cmd.ExecuteNonQuery()
cmd.CommandText = "exec sp_addrolemember N’db_owner’, N’" + account + "’"
cmd.ExecuteNonQuery()
Catch ex As Exception

End Try

cn.Close()
End Function

Public Function GrantDBAccessInteg(ByVal connectionString As String, ByVal account As String, ByVal password As String)
Dim cn As New SqlConnection(connectionString)
cn.Open()

Dim cmd As New SqlCommand
cmd.Connection = cn
Try
cmd.CommandText = "exec sp_addlogin N’" + account + "’, N’" & password & "’"
cmd.ExecuteNonQuery()
cmd.CommandText = "exec sp_grantdbaccess N’" + account + "’"
cmd.ExecuteNonQuery()
cmd.CommandText = "exec sp_addrolemember N’db_owner’, N’" + account + "’"
cmd.ExecuteNonQuery()
Catch ex As Exception

End Try

cn.Close()
End Function

#End Region

End Module

2004-7-15 18:48:25 192.168.0.125

★第11★楼 vb4 ★引用 ★删除



张叶 ’ Get the files from the current parent.
aFiles = Directory.GetFiles(sourceDir)
’ Copy all files.
For i = 0 To aFiles.GetUpperBound(0)
sFile = Path.GetFileName(aFiles(i))
’ Copy the file.
File.Copy(aFiles(i), destDir + sFile, True)
Next i

End Sub

Public Sub CopyFolder(ByVal source As String, ByVal destination As String)
Console.WriteLine("Copying folder " & source & " -〉 " & destination)
RecursiveCopyFiles(source, destination, True)
End Sub

Public Sub CopyFile(ByVal source As String, ByVal destination As String)
Console.WriteLine("Copying file " & source & " -〉 " & destination)
File.Copy(source, destination)
End Sub

Public Function GetLastDirectoryName(ByVal directory As String) As String
Dim posSep As Integer = directory.LastIndexOf("/")
’ Get the path of the source directory.
Return directory.Substring((posSep + 1), directory.Length - (posSep + 1))
End Function
#End Region


#Region "Database"
Public Sub CreateDatabase(ByVal DBName As String)
Try
Dim sqlConn As New SqlConnection("server=localhost;trusted_connection=true;database=master")
Dim sqlComm As New SqlCommand("CREATE DATABASE " & DBName, sqlConn)
sqlConn.Open()
sqlComm.ExecuteNonQuery()
sqlConn.Close()
Catch ex As Exception
Console.WriteLine("SqlException Message: " & ex.Message)
Console.WriteLine("Hit Enter to Exit")
Console.ReadLine()
End Try
End Sub
Public Function ExecuteSQL(ByVal Path As String, ByVal DBName As String) As Boolean
Dim sr As New StreamReader(Path)
Dim sql As String = sr.ReadToEnd()
sr.Close()
Try
Dim sqlConn As New SqlConnection("server=localhost;trusted_connection=true;database=" & DBName)
Dim sqlComm As New SqlCommand(sql, sqlConn)
sqlConn.Open()
sqlComm.ExecuteNonQuery()
sqlConn.Close()
Catch ex As Exception
Console.WriteLine("SqlException Message: " & ex.Message)
Console.WriteLine("Hit Enter to Exit")
Console.ReadLine()
End Try
End Function
Public Function ExecuteOSQL(ByVal Path As String)
Try
’Embed a quoted path
Dim appPath As String = GetCurrentPath()
Dim startInfo As New ProcessStartInfo("OSQL.EXE")
startInfo.Arguments = "-E -i """ & appPath & "/" & Path & ""
Dim proc As Process = Process.Start(startInfo)
proc.WaitForExit()
Catch ex As Exception
Console.WriteLine(ex.Message)
Console.Write("Hit enter to exit")
Console.ReadLine()
End Try
End Function

2004-7-15 18:48:12 192.168.0.125

★第10★楼 vb3 ★引用 ★删除



张叶 #Region "File I/O"

Public Sub CreateDirectory(ByVal DirectoryName As String)
Try
If Directory.Exists(DirectoryName) Then
Directory.Delete(DirectoryName, True)
End If
Directory.CreateDirectory(DirectoryName)
Catch ex As Exception
Console.WriteLine(ex.Message)
Console.WriteLine("Hit enter to exit")
Console.ReadLine()
End Try
End Sub

Public Sub DeleteFile(ByVal FileName As String)
Try
Console.WriteLine("Deleting : " & FileName)
File.Delete(FileName)
Catch ex As Exception
Console.WriteLine(ex.Message)
Console.WriteLine("Hit enter to exit")
Console.ReadLine()
End Try
End Sub

Public Sub DeleteAllSubFolders(ByVal FolderRoot As String)
Dim dir As New DirectoryInfo(FolderRoot)
Dim di As DirectoryInfo
For Each di In dir.GetDirectories()
di.Delete(True)
Next di
Dim fi As System.IO.FileInfo
For Each fi In dir.GetFiles()
fi.Delete()
Next fi
End Sub

Public Sub DeleteFolder(ByVal FolderName As String)
Try
If Directory.Exists(FolderName) Then
Console.WriteLine("Deleting Folder: " & FolderName)
Directory.Delete(FolderName, True)
End If
Catch ex As Exception
Console.WriteLine(ex.Message)
Console.WriteLine("Hit enter to exit")
Console.ReadLine()
End Try
End Sub
’ Recursively copy all files and subdirectories from the
’ specified source to the specified destination.
Public Sub RecursiveCopyFiles( _
ByVal sourceDir As String, _
ByVal destDir As String, _
ByVal fRecursive As Boolean)

Dim i As Integer
Dim posSep As Integer
Dim sDir As String
Dim aDirs() As String
Dim sFile As String
Dim aFiles() As String

’ Add trailing separators to the supplied paths if they don’t exist.
If Not sourceDir.EndsWith(System.IO.Path.DirectorySeparatorChar.ToString()) Then
sourceDir &= System.IO.Path.DirectorySeparatorChar
End If

If Not destDir.EndsWith(System.IO.Path.DirectorySeparatorChar.ToString()) Then
destDir &= System.IO.Path.DirectorySeparatorChar
End If

If Not Directory.Exists(destDir) Then
Directory.CreateDirectory(destDir)
End If

’ Recursive switch to continue drilling down into dir structure.
If fRecursive Then

’ Get a list of directories from the current parent.
aDirs = Directory.GetDirectories(sourceDir)
For i = 0 To aDirs.GetUpperBound(0)
’ Get the path of the source directory.
sDir = GetLastDirectoryName(aDirs(i))
’ Create the new directory in the destination directory.
Directory.CreateDirectory(destDir + sDir)
’ Since we are in recursive mode, copy the children also
RecursiveCopyFiles(aDirs(i), (destDir + sDir), fRecursive)
Next

End If


2004-7-15 18:47:42 192.168.0.125

★第9★楼 vb2 ★引用 ★删除



张叶 #Region "COM"
Public Sub RegisterCOMDLL(ByVal component As String, ByVal Quiet As Boolean)
Try
Dim startInfo As New ProcessStartInfo("Regsvr32")
If Quiet Then
startInfo.Arguments = "/S " & component & ""
Else
startInfo.Arguments = component
End If
Dim proc As Process = Process.Start(startInfo)
proc.WaitForExit()
Catch ex As Exception
Console.WriteLine(ex.Message)
Console.Write("Hit enter to exit")
Console.ReadLine()
End Try

End Sub
#End Region

#Region "WebApps"
Public Sub InstallWebs()
ResetIIS()
For Each webSite As String In Directory.GetDirectories(GetCurrentPath() & "/WebSites")
ReinstallWebApp(webSite)
Next
End Sub

Public Sub ReinstallWebApp(ByVal webSite As String)
UninstallWebApplication(webSite)
CreateWebApp(webSite)
End Sub

Public Sub CreateWebApp(ByVal webSite As String)
Dim DirObj As Object
Console.WriteLine("Creating Web Application for IIS://LocalHost/W3SVC/1/ROOT/" & webSite)
DirObj = GetObject("IIS://LocalHost/W3SVC/1/ROOT")
Console.WriteLine("Creating Virtual Directory for IIS://LocalHost/W3SVC/1/ROOT/" & webSite)
Dim mywd As Object = DirObj.Create("IIsWebVirtualDir", GetLastDirectoryName(webSite))
mywd.setinfo()
mywd.AppCreate(True)
mywd.path = webSite
mywd.setinfo()
End Sub

Sub UninstallWebApplication(ByVal webSite As String)
Try
Dim DirObj As Object
DirObj = GetObject("IIS://LocalHost/W3SVC/1/ROOT")
DirObj.delete("IIsWebVirtualDir", GetLastDirectoryName(webSite))
Catch exc As Exception
End Try
End Sub
#End Region


2004-7-15 18:43:02 192.168.0.125

★第8★楼 vb1 ★引用 ★删除



张叶 Imports System.IO
Imports System.Data
Imports System.Data.SqlClient
Imports System.ServiceProcess
Imports System.DirectoryServices
Imports System.Runtime.InteropServices

Module Utils
Public WebRoot As String = "C:/inetpub/wwwroot"

#Region "Users and Groupd"

Const UF_SCRIPT As Integer = 1
Const UF_ACCOUNTDISABLE As Integer = 2
Const UF_HOMEDIR_REQUIRED As Integer = 8
Const UF_LOCKOUT As Integer = 16
Const UF_PASSWD_NOTREQD As Integer = 32
Const UF_PASSWD_CANT_CHANGE As Integer = 64
Const UF_TEMP_DUPLICATE_ACCOUNT As Integer = 256
Const UF_NORMAL_ACCOUNT As Integer = 512

Public Sub CreateUser(ByVal userName As String, ByVal password As String)
Dim NewUser As DirectoryEntry
Dim AD As New DirectoryEntry("WinNT://" + Environment.MachineName + ",computer")
Try
NewUser = AD.Children.Find(userName, "user")
AD.Children.Remove(NewUser)
Catch ex As COMException

End Try

NewUser = AD.Children.Add(userName, "user")
NewUser.Properties("description").Add(userName)

NewUser.Properties("userFlags").Add(UF_NORMAL_ACCOUNT)

’ invoke native method ’SetPassword’ before commiting
’ for domain accounts this must be done after commiting

NewUser.Invoke("SetPassword", New Object() {password})
NewUser.CommitChanges()

’ Add user to guests
’ DirectoryEntry(grp = AD.Children.Find("Guests", "group"))
’if (grp.Name != null)
’grp.Invoke("Add", new Object[] {NewUser.Path.ToString()});
Console.WriteLine(userName & " account created successfully")

End Sub
#End Region


#Region "Paths"
Public Function GetCurrentPath() As String
Return Directory.GetCurrentDirectory()
End Function
#End Region

#Region "Services"
Public Sub ResetIIS()
Console.WriteLine("Restarting IIS")
Dim startInfo As New ProcessStartInfo("IISRESET")
startInfo.UseShellExecute = True
Dim proc As Process = Process.Start(startInfo)
proc.WaitForExit()
Console.WriteLine("IIS Restart Complete")
End Sub

Public Sub StopService(ByVal ServiceName As String)
Console.WriteLine("Stopping Service: " & ServiceName)
Try
Dim srv As New ServiceController(ServiceName, Environment.MachineName)
srv.Stop()
srv.WaitForStatus(ServiceControllerStatus.Stopped)
Catch ex As Exception
Console.WriteLine(ex.Message)
Console.WriteLine("Hit enter to exit")
Console.ReadLine()
End Try
End Sub

Public Sub StartService(ByVal ServiceName As String)
Console.WriteLine("Starting Service: " & ServiceName)
Try
Dim srv As New ServiceController(ServiceName, Environment.MachineName)
srv.Start()
srv.WaitForStatus(ServiceControllerStatus.Running)
Catch ex As Exception
Console.WriteLine(ex.Message)
Console.WriteLine("Hit enter to exit")
Console.ReadLine()
End Try
End Sub

#End Region








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值