The Lanham Factor
The (ir)rational thoughts of a (not-so)mad man

Create & Destory IIS Virtual Directories - Programmatically

Thursday, November 10, 2005 5:28 PM

This article describes a simple WinForms utility that creates / destroys Microsoft(R) Internet Information Server(R) (IIS) Virtual Directories programmatically.  The utility is then embedded in an Installer Project through Microsoft(R) Visual Studio .NET(R) 2003.  I originally wrote this utility a few years ago when a client wanted an installer without buying an installer product AND did not want to always install to the default Web.  In doing some research I became curious about not just creating and destroying virtual directories programmatically but also integrating these features with an installation project.

Create the Utility

Start by creating a VB.NET WinForms project called “VIT.WebSetup”.  To this project, add a module “MainMod” and add two forms including “frmWebSetup.vb” and “frmWebTeardown.vb”.  (Sorry about the names...some old habits die hard.  I've since migrated away from that.)  The utility is command-line driven and the “MainMod” module drives which form is shown based on the command-line parameters. The “Web Setup” form is the form used to specify the parameters for and create the virtual directory.  It is linked to the installer during the “Commit“ portion of the installation process.  View the Web Setup form screenshot.  The “Web Teardown“ form is used to delete a virtual directory by name and is used during the “Uninstall“ portion of the installation process.  View the Web Teardown form screenshot.

Add Some Code

Next, add some code.  The code for the main module is responsible for parsing the command line and invoking the appropriate form.  The code for each form is extremely straightforward.  The “Web Setup” form contains two custom methods and three event handlers.  The “Web Teardown” form contains one custom method and two event handlers. 

“MainMod“ Methods

Main - This is the method by which the application starts.  You must specify this method as the starting point for the application in the project properties.  This method relies on the ProcessCommandLine method to parse the command line into a HashTable.

ProcessCommandLine - This method parses the command line into a HashTable object based on the presence or absence of the forward slash.

Here is the code for the main module.

Public Sub Main(ByVal args() As String)

Dim frmSetup As frmWebSetup

Dim frmTeardown As frmWebTeardown

Dim cmd As Hashtable

If args.Length > 0 Then

cmd = ProcessCommandLine(args)

If Not (cmd Is Nothing) Then

If cmd.Contains("u") Then ' Destroy or "unmake" a virtual directory.

frmTeardown = New frmWebTeardown

Try

frmTeardown.txtVirtDirName.Text = cmd.Item("u").ToString()

Catch ex As System.NullReferenceException

' Do NO OP

' This occurs of the "/" isn't used to specify parms

' OR

' if a switch is empty.

Catch ex As Exception

' Do NO OP

End Try

frmTeardown.ShowDialog()

frmTeardown = Nothing

Else ' Create a Virtual Directory

frmSetup = New frmWebSetup

Try

frmSetup.txtVirtDirName.Text = cmd.Item("n").ToString()

frmSetup.txtVirtDirAlias.Text = cmd.Item("a").ToString()

frmSetup.txtVirtDirPath.Text = cmd.Item("d").ToString()

Catch ex As System.NullReferenceException

' Do NO OP

' This occurs if the "/" isn't used to specify parms

' OR

' if a switch is empty.

Catch ex As Exception

' Do NO OP

End Try

frmSetup.ShowDialog()

frmSetup = Nothing

End If

 

End If

End If

cmd = Nothing

End Sub

Private Function ProcessCommandLine(ByVal cmdargs() As String) As Hashtable

Dim ret As Hashtable

If cmdargs.Length Mod 2 = 0 Then

ret = New Hashtable(CInt(cmdargs.Length / 2I))

For i As Integer = 0 To cmdargs.Length - 1 Step 2

ret.Add(cmdargs(i).ToString.ToLower.Replace("/", ""), cmdargs(i + 1).ToString())

Next

Else

ret = New Hashtable(cmdargs.Length)

For i As Integer = 0 To cmdargs.Length - 1

ret.Add(i.ToString, cmdargs(i))

Next

End If

Return ret

End Function

“Web Setup“ Methods

CreateVirtualDirectory - This method, surprise surprise, is responsible for actually creating the virtual directory.  It utilizes the Active Directory(R) Services Interface (ADSI) to perform its functions based on five parameters.  The “VirtDirName“ String parameter specifies the name of the virtual directory to be created.  The “VirtDirPath“ String paramter specifies the location of the virtual directory on the file system.  The “ReadAccess“ and “ScriptAccess“ Boolean paramters are used to indicate the permissions for the virtual directory.  Finally, the “VirtDirAlias“ String parameter specifies...you guessed it...the alias of the virtual directory.

IsValidInput - This method simply validates the input from the text fields on the form.  It takes no parameters and actually simply checks that the text fields contain data.  It performs no other validation.

btnBrowse_Click Event Handler - This handler invokes an “Open File Dialog“, allowing the user to select a directory which becomes the path to the virtual directory.

btnCreateVirtDir_Click Event Handler - This handler invokes the IsValidInput and CreateVirtualDirectory methods to actually create the virtual directory based on the input provided by the user. 

btnCancel_Click Event Handler - Do I really need to explain this one?

Here is the code for this form:

Private Sub CreateVirtualDirectory(ByVal VirtDirName As String, ByVal VirtDirPath As String, ByVal ReadAccess As Boolean, ByVal ScriptAccess As Boolean, ByVal VirtDirAlias As String)

Dim IIsWebVDirRootObj As Object

Dim IIsWebVDirObj As Object

' Create an instance of the virtual directory object

' that represents the default Web site.

IIsWebVDirRootObj = GetObject("IIS://localhost/W3SVC/1/Root")

' Use the Windows ADSI container object "Create" method to create

' a new virtual directory.

IIsWebVDirObj = IIsWebVDirRootObj.Create("IIsWebVirtualDir", VirtDirName)

' Use the Windows ADSI object "Put" method to

' set some required properties.

IIsWebVDirObj.Put("Path", VirtDirPath)

IIsWebVDirObj.Put("AccessRead", ReadAccess)

IIsWebVDirObj.Put("AccessScript", ScriptAccess)

' Use the AppCreate2 method of the IIS ADSI provider to

' create an application on the new virtual directory.

IIsWebVDirObj.AppCreate2(1)

IIsWebVDirObj.Put("AppFriendlyName", VirtDirAlias)

' Use the Windows ADSI object "SetInfo" method to

' save the data to the metabase.

IIsWebVDirObj.SetInfo()

 

End Sub

Private Function IsValidInput() As Boolean

Dim result As Boolean = True

result = result And (Me.txtVirtDirName.Text.Trim.Length > 0)

result = result And (Me.txtVirtDirPath.Text.Trim.Length > 0)

result = result And (Me.txtVirtDirAlias.Text.Trim.Length > 0)

Return result

End Function

Private Sub btnBrowse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBrowse.Click

If Me.ofdBrowse.ShowDialog() = DialogResult.Cancel Then

Else

Me.txtVirtDirPath.Text = ofdBrowse.SelectedPath

End If

End Sub

Private Sub btnCreateVirtDir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCreateVirtDir.Click

If Me.IsValidInput() Then

Try

Me.CreateVirtualDirectory(Me.txtVirtDirName.Text, Me.txtVirtDirPath.Text, Me.chkAccessRead.Checked, Me.chkAccessScript.Checked, Me.txtVirtDirAlias.Text)

MessageBox.Show("The virtual directory was successfully created.")

Catch ex As System.Runtime.InteropServices.COMException

MessageBox.Show("The following COM exception occurred: " & ex.Message)

Catch ex As Exception

MessageBox.Show("The following exception occurred: " & ex.Message)

End Try

Else

MessageBox.Show("Required Fields are Missing")

End If

End Sub

Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click

If DialogResult.Yes = MessageBox.Show("Are you sure you want to stop creating virtual directories?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) Then

Application.Exit()

End If

End Sub

“Web Teardown“ Methods

btnDestroyVirtDir_Click Event Handler - You betcha!  This uses basically the same technique as the CreateVirtualDirectory method of the “Web Setup” form.  Instead of creating, of course, it destroys the virtual directory specified by the user.

The “Web Teardown” form also contains IsValidInput and btnCancel_Click Event Handler methods, like the “Web Setup” form.  Here is the code for this form.

Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click

If DialogResult.Yes = MessageBox.Show("Are you sure you want to stop destroying virtual directories?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) Then

Application.Exit()

End If

End Sub

Private Sub btnDestroyVirtDir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDestroyVirtDir.Click

Dim IIsWebVDirObj As Object

Dim IIsWebDirRoot As Object

If Me.IsValidInput Then

Try

IIsWebVDirObj = GetObject("IIS://localhost/W3SVC/1/ROOT/" & Me.txtVirtDirName.Text)

IIsWebVDirObj.AppDeleteRecursive()

IIsWebVDirObj.SetInfo()

IIsWebVDirObj = Nothing

IIsWebDirRoot = GetObject("IIS://localhost/W3SVC/1/ROOT")

IIsWebDirRoot.Delete("IIsWebVirtualDir", Me.txtVirtDirName.Text)

IIsWebDirRoot = Nothing

MessageBox.Show("The virtual directory was successfully destroyed.")

Catch ex As System.Runtime.InteropServices.COMException

MessageBox.Show("The following COM exception occurred: " & ex.Message)

Catch ex As Exception

MessageBox.Show("The following exception occurred: " & ex.Message)

End Try

Else

MessageBox.Show("Required Fields are Missing")

End If

End Sub

Private Function IsValidInput() As Boolean

Dim result As Boolean = True

result = result And (Me.txtVirtDirName.Text.Trim.Length > 0)

Return result

End Function

 

Integrating with a Setup Project

Now that the Web Setup utility is built, it can be used from a setup project.  There are basically two areas of customization in the setup project for integrating the utility.  Firstly, the “File System Editor” is used to include the utility.  Secondly, the “Custom Actions Editor” is used to invoke the utility.

File System Editor Configuration

The utility must be included with the distribution to be invoked.  There are two ways to do this and they both follow the same basic steps.  You can include the “Primary Output” from the “WebSetup” project.  Alternately, you can include the stand-alone executable resulting from building the “Web Setup” project.

Including the “Primary Output”

  1. Open the “File System Editor“
  2. Right-Click “Application Folder -> Add -> Project Output...“
  3. Choose the “WebSetup“ project from the “Project“ pick list and select “Primary Output“.
  4. Click “OK“.

Including the Executable

  1. Open the “File System Editor“
  2. Right-Click “Application Folder -> Add -> File...“
  3. Locate the .exe file and click “Open“.

Custom Actions Editor Configuration

Once the “WebSetup” file is included, modify the custom actions to invoke the utility.  Remember that the utility supports both creation and destruction of virtual directories so custom actions should be created for each.  Follow these steps to properly configure the custom actions.  Note that you do not want to create a virtual directory until the install is successful, so you will use the “Commit“ area for the creation custom action. 

Configuring to Create Virtual Directories

  1. Open the “Custom Actions Editor“.
  2. Right-Click on “Commit“ and choose “Add Custom Action...“
  3. Double-Click “Application Folder“ and choose either the “Primary Output...“ or executable file name, depending on which you chose to include.
  4. Right-Click on the newly created custom action and select “Rename“.
  5. Rename the custom action to “Create Virtual Directory“.
  6. While the custom action is selected, view its properties.
  7. Change the “Arguments“ property to read: /d [TARGETDIR] /a alias /n name
  8. Substitute your alias for “alias“ and your virtual directory name for “name“.  Leave the target directory as shown to pull the target directory from the selected installation folder.

Configuring to Delete Virtual Directories

  1. Open the “Custom Actions Editor“.
  2. Right-Click on “Uninstall“ and choose “Add Custom Action...“
  3. Double-Click “Application Folder“ and choose either the “Primary Output...“ or executable file name, depending on which you chose to include.
  4. Right-Click on the newly created custom action and select “Rename“.
  5. Rename the custom action to “Destory Virtual Directory“.
  6. While the custom action is selected, view its properties.
  7. Change the “Arguments“ property to read: /u name
  8. Substitute your virtual directory name for “name“.

Next Steps

There are some things that can be done to improve this utility. 

  1. Some better validation can occur.
  2. Consider reading virtual directories from ADSI, providing some user guidance.
  3. Review this URL for the same basic approach with some other ADSI parameters included:  http://www.vbforums.com/showthread.php?t=347207http://www.vbforums.com/showthread.php?t=347207

 




Feedback

# re: Create & Destory IIS Virtual Directories - Programmatically

In the custom action properties, you need to set installerclass = false or it will error on not finding websetup.installstate. I am using this to create a virtual directory underneath the web application being installed (for some common web elements). So I'm not using [targetdir], just pointing to the common app directory under wwwroot.
To do this, I'm using name=webapp/common, alias=common, directory=<common web app directory>.
Seems to work.
Thanks for this utility!!!
Toby 8/17/2006 8:52 AM | Toby

# re: Create & Destory IIS Virtual Directories - Programmatically

This is the fantanstic article. for virual directory operation. U had saved my life..

Right now, In my Application i m trying to open web application into windows application. which required. this windows application must be configured before it usage.

Thanks for this article.
You are awsome.

Thanks buddy.
Vachan Chauhan
Software Engineer 8/30/2007 4:52 AM | Vachan

# re: Create & Destory IIS Virtual Directories - Programmatically

I'm glad you were able to make use of it! Thank you for the positive feedback! Don't forget to post any suggestions you have or any snags you experience while deploying your own solution.
8/31/2007 5:06 PM | codesailor

# re: Create & Destory IIS Virtual Directories - Programmatically

HI:

I've created a Web Setup project. I'm trying to set additional IIS settings like Authentication, Executables, add the .ajaxjs Extension. Can you please suggest how can i achieve. I'm using Orca to edit some settings for IIS already.
9/6/2008 3:48 PM | MK

# re: Create & Destory IIS Virtual Directories - Programmatically

Hell this code doest work for creating virtual directory at remote system. please advise how to do that? 5/28/2009 3:07 AM | swati

# re: Create & Destory IIS Virtual Directories - Programmatically

Thanks for the post, works great! I modified it a bit to suit my own needs, but it's working awesome. The only thing I had to do with your code was encapsulate [TARGETDIR] in quotes so it was parsed correctly and was read at runtime, other than that it can be used as is and I'm sure it's helped a lot of people. Cheers! 6/16/2010 10:57 PM | Jim

# re: Create & Destory IIS Virtual Directories - Programmatically

This is exactly the utility I need but I'm having trouble getting it to work. I don't understand how the code should be placed and in what files. Could you attach your example project code for this utility? 7/8/2010 3:39 PM | Katelyn

Post a comment