Modifying Internet Information Services During Deployment with Custom Actions
David Guyer, Tarik Nesh-Nash and Steve Hoag
Visual Studio Team
Summary: This paper demonstrates how to set Internet Information Services (IIS) settings that are not exposed by Web Setup projects using either Installer classes or script. (10 printed pages)
Creating the Web Project
Setting IIS Properties Using a Managed Installer Class
Add the Installer Class to the Web Application Project
Add a Web Setup Project to the Solution
Add the Project Outputs to the Web Setup Project
Add the Installer Class as a Custom Action
Configure the Custom Action
Setting IIS Properties Based on User Input
Add a Custom User Interface Dialog Box
Edit the Installer Class Code
Modify the Custom Action
Web Setup projects in Microsoft® Visual Studio® .NET expose the most common settings for Web Folders in Internet Information Services as folder properties; however, not all settings or properties that may need to be modified when installing a Web application are exposed. For example, it is necessary to turn off anonymous access for an ASP.NET Web application in order to determine the user name of the Web client, but the AuthAnonymous property is not exposed by the Web Setup project. A custom action can be used during installation to set these additional properties.
Internet Information Services (IIS) reveals most of these properties through IIS objects. Information on these IIS objects and properties can be found in the Visual Studio .NET documentation by searching for IIS Admin Objects: reference in the index.
This paper provides a code example using a managed installer class and Visual Basic® .NET. The code for the managed installer class can be replaced with code written in any language supported by Visual Studio .NET. Rather than using an installer class, you could also write a custom action using a scripting language such as VBScript. Script custom actions are less capable, and more difficult to debug, but they can be used for installations where the common language runtime is not available (for example, C++ ATL Web Server projects).
The code examples modify the AuthAnonymous property using the syntax
IISVdir.AuthAnonymous = False. If you want to set other properties, you can change this code to set the appropriate property based on the documentation. The code examples use the SetInfo method to commit the changes to the server.
The Installation Address dialog box displayed during installation allows the installing user to specify the Virtual Directory and Port where the Web application will be installed. On Windows® 2000 Server and Windows Server 2003, multiple Web servers can be hosted on a single computer. The Web Setup can only install to an active Web server on a TCP port. As a result, the Port property in the Installation Address dialog box identifies the Web server that the Virtual Directory is created on. A custom action or script must be able to identify the correct Web server based on the port.
An additional example is included that demonstrates how to display a dialog box during installation to allow the user to select additional IIS properties to be set.
In order to modify the IIS settings during deployment, you must first have a Web application to deploy. You can use any Web application that you have already created using Visual Studio .NET, or you can create an empty Web application project as described below.
To create the Web application project
- On the File menu, point to New and then click Project to display the New Project dialog box.
- In the Project Types pane, select either Visual Basic or Visual C#.
- In the Templates pane, select Empty Web Project.
- In the Location text box, specify the URL where you want to place the Web project, including the name you want to give it.
- Click OK to create the Web project.
Visual Studio connects to the server and adds the appropriate project items to Solution Explorer in the project node.
Managed installer classes (also known as installation components) allow you to set up custom actions that will occur when your application is deployed. In this example, a managed installer class is used to expose code that sets the IIS AuthAnonymous property. The following steps will create an installer class, add code to set the IIS property, and provide a FindServerNum function to iterate through the server and find the port where the Web application is installed.
To add an installer class
- On the Project menu, choose Add New Item.
- In the Add New Item dialog box, double-click Installer Class to add it to the project.
- Add the following procedure to override the Install procedure of the base class:
Public Overrides Sub Install(ByVal stateSaver As _ System.Collections.IDictionary) Dim strVDir As String = Me.Context.Parameters.Item("VDir") Dim intServerNum As Integer = _ Me.FindServerNum(Me.Context.Parameters.Item("Port")) Dim strObjectPath As String = "IIS://" & _ System.Environment.MachineName & "/W3SVC/" & _ intServerNum.ToString & "/ROOT/" & strVDir Dim IISVdir As Object ' Gets the IIS VDir Object. IISVdir = GetIISObject(strObjectPath) ' Set the AuthAnonymous property here. IISVdir.AuthAnonymous = False ' Uses SetInfo to save the settings to the Server. IISVdir.SetInfo() End Sub
- Add the following function below the Install procedure and before the End Class statement:
Public Function FindServerNum(ByVal strPort As String) As Integer Const MD_SERVER_STATE_STARTED = 2 Dim MachineName As String Dim IISObjectPath As String Dim IISObject As Object Dim ChildObject As Object Dim ChildObjectName As String Dim Servers As New Collection() Dim ServerNum As Integer Dim i As Integer Dim strBindings As String Dim strSvrPort As String Dim BindArray As Array MachineName = System.Environment.MachineName IISObjectPath = "IIS://" & MachineName & "/W3SVC" ' Iterates through the W3SVC folder to get the name of ' each child object. IISObject = GetIISObject(IISObjectPath) For Each ChildObject In IISObject ChildObjectName = ChildObject.AdsPath ChildObjectName = Right(ChildObjectName, Len(ChildObjectName) _ - InStrRev(ChildObjectName, "/")) Try ' If the name can be converted to an integer (port number), ' add it to the Servers collection. ServerNum = CType(ChildObjectName, Integer) Servers.Add(ServerNum) Catch ' If the name cannot be converted to an integer, ' it isn't a port and can be ignored. End Try Next ' Iterates through each server, removing each inactive server ' without the correct port. For i = Servers.Count To 1 Step -1 IISObjectPath = "IIS://" & MachineName & "/W3SVC/" & _ Servers(i) IISObject = GetIISObject(IISObjectPath) ' Gets the Port Number of the current IISObject. BindArray = IISObject.ServerBindings strBindings = BindArray(0) strSvrPort = Left(strBindings, InStrRev(strBindings, _ ":") - 1) strSvrPort = Right(strSvrPort, Len(strSvrPort) - _ InStr(strSvrPort, ":")) ' Determines if this is our server. IIS can only have one ' active port, so if the port is active it is the port where ' the application is installed. If strPort = strSvrPort Then If IISObject.ServerState = MD_SERVER_STATE_STARTED Then Return Servers(i) End If Else ' Not the active Port, so remove it from the ' collection. Servers.Remove(i) End If Next ' Checks how many servers are left. If one, we've found it ' otherwise, report an error. Select Case Servers.Count Case 0 Err.Raise(9999, "FindServerNum", "No Active Servers with _ " & "the requested port were found. Port=" & strPort & _ ". ") Case 1 Return Servers(1) Case Else Err.Raise(9999, "FindServerNum", "More than one Active _ servers with the requested port were found. Port=" & _ strPort & ". ") End Select End Function Private Function GetIISObject(ByVal strFullObjectPath As String) As Object Dim IISObject As Object Try IISObject = GetObject(strFullObjectPath) Return IISObject Catch exp As Exception Err.Raise(9999, "GetIISObject", "Error opening: " _ & strFullObjectPath & ". " & exp.Message) End Try End Function
The Web Setup project is used to create Windows Installer (.msi) file that will be used to install the Web application on a Web server.
To add a Web setup project
- On the File menu, point to Add Project, and then choose New Project.
- In the Add New Project dialog box, select Setup and Deployment Projects in the Project Type pane, and then choose Web Setup Project in the Templates pane. In the Name box, type the name of your Web Application and Setup.
The project is added to Solution Explorer, and the File System Editor opens.
- In the Properties window, select the ProductName property and type the name of your Web Application.
The next step is to associate your Web application with the Web Setup project by adding project outputs. The project outputs in this case include the Web application, any content files, and the managed installer class.
To add project outputs
- In the File System Editor, select the Web Application Folder.
- On the Action menu, point to Add, and then choose Project Output.
- In the Add Project Output Group dialog box, choose your Web Application from the Project drop-down list.
- Select the Primary Output and Content Files groups from the list and click OK.
A custom action allows you to run code at the end of an installation to perform actions that cannot be accomplished by the installer — for example, setting IIS properties that are not exposed by the Web Setup project. In this case, the custom action that will be run is the Installer class, which is contained in the primary output of your Web Application project.
To add a custom action
- Select your Web Setup project in Solution Explorer.
- On the View menu, point to Editor, and choose Custom Actions.
- In the Custom Actions Editor, select the Install node. On the Action menu, choose Add Custom Action.
- In the Select Item in Project dialog box, double-click the Web Application Folder.
- Select the Primary output from WebApp (Active) item, where WebApp is the name of your Web Application, then click OK.
In order to set the IIS properties, the custom action needs to know the virtual directory and port where the application will be installed. This is accomplished using the CustomActionData property.
To configure the custom action
- In the Custom Actions Editor, select the custom action that you added in the previous step.
- In the Properties window, select the CustomActionData property and type /VDIR=[TARGETVDIR] /PORT=[TARGETPORT].
This specifies that the CustomActionData property will return a string containing the virtual directory (the [TARGETVDIR] property) and the port (the [TARGETPORT] property) entered by the user during installation.
At this point, you are ready to build the Web Setup project and install your Web Application. The next section demonstrates additional steps to allow the person installing the application to choose IIS settings during installation.
This section builds upon the previous steps to demonstrate additional steps that may be used to accept user input for additional IIS settings. In this case, you will present a dialog box that allows the user to determine whether to enable ASP Buffering. ASP Buffering determines whether the processing of a Web page must be finished before the page is displayed.
A custom User Interface Dialog Box collects user input during installation. In this case, you will use a dialog box that presents a check box to the user. This dialog box will be shown during installation just before the Installation Address dialog box.
To create a custom installation dialog
- Select the Web Setup project in Solution Explorer.
- On the View menu, point to Editor, and choose User Interface.
- In the User Interface Editor, select the Start node under Install. On the Action menu, choose Add Dialog.
- In the Add Dialog dialog box, double-click the Checkboxes (A) dialog box.
- On the Action menu, choose Move Up. Repeat until the Checkboxes (A) dialog box is above the Installation Address node.
- In the Properties window, set the following properties:
Property Setting Description BannerText Web Site Configuration Specifies text to be displayed in the banner area of the dialog box. BodyText Select your IIS settings for this application Specifies text to be displayed in the body of the dialog box. Checkbox1Label Enable ASP Buffering Specifies the label text for the first CheckBox control on the dialog box. Checkbox 2Visible false Hides the second CheckBox control. Checkbox 3Visible false Hides the third CheckBox control. Checkbox 4Visible false Hides the fourth CheckBox control.
The next step is to modify the code for the Installer class to update the Buffering property.
To modify the Installer class
- Select the Installer class (Installer.vb) in Solution Explorer, and press F7 to open the Code Editor.
- In the Install procedure, locate the line that reads
Dim IISVdir As Object.
- Immediately beneath this line, add the following code:
Dim blnBuffering As Boolean If Context.Parameters.Item("BUFFERING") = "1" Then blnBuffering = true Else blnBuffering = false End If
- Locate the line of code that reads
IISVdir.AuthAnonymous = False.
- Immediately beneath this line, add the following code:
IISVdir.AspBufferingOn = blnBuffering
The final step is to modify the CustomActionData property for the custom action to include the value returned by the Checkbox1Property property of the custom dialog.
To modify the custom action
- Select the Web Setup project in Solution Explorer, and open the Custom Actions Editor.
- In the Custom Actions Editor, select the custom action that you added earlier.
- In the Properties window, select the CustomActionData property and type /VDIR=[TARGETVDIR] /PORT=[TARGETPORT] /BUFFERING=[CHECKBOXA1].
This adds the Boolean value of the check box (the [CHECKBOXA1] property) to the string returned by the CustomActionData property.
Once again you are ready to build the Web Setup project and install your Web Application. During installation you will see the custom Web Site Configuration dialog box with the Enable ASP Buffering check box that allows you to specify the setting for the IIS Buffering property. After installation you can inspect the IIS settings on your server to verify that the properties were set correctly.
Although not all IIS properties are exposed by a Web Setup project, setting IIS properties with a custom action is relatively easy. Although this paper only demonstrates two properties, you can modify the code to handle any of the properties of any IIS object.