Duplicating Virtual Directories

As I develop the Exploring XML column, I frequently switch between two machines—my laptop and my desktop computer. And because I frequently use XML for SQL Server 2000 Web Release 3 (SQLXML 3.0) virtual directories in the example code, alternating between computers makes it necessary for me to configure identical virtual directories on both machines. To complete the switch, I have to move all the files I use in the examples on one machine to the other machine and configure the virtual directory using the proper settings. WinZip archives all the files, including the directory structure, so I can easily move the files to the other machine. But configuring the virtual directory has been more problematic. I've used Microsoft Management Console's (MMC's) Configure IIS Support plug-in supplied with SQL Server 2000 or with a SQLXML release. But this method has at least two drawbacks. One, I repeatedly checked the MMC on both machines to make sure that the settings were identical. And two, I discovered that many of the bugs I had to track down were caused by my failure to set up the virtual directory properly. What I really needed was a way to capture the virtual directory settings so that I could transfer them between machines without having to use the MMC, just like I did with the zip archive.

To solve this problem, I wrote a small Visual Basic (VB) program—DuplicateVDir—which creates an executable VBScript program that I can move to another machine, then run to create a copy of a virtual directory. DuplicateVDir uses the Virtual Directory Management Object Model—which I call VDOM—to create a new virtual directory. VDOM is included with SQL Server 2000 and all versions of SQLXML. By combining DuplicateVDir with a zip archive that contains the physical directory structure and files, I can conveniently and accurately copy a virtual directory between machines.

Let's take a high-level overview of DuplicateVDir and see how it uses VDOM to read the properties of a virtual directory. Then, let's examine the script that DuplicateVDir generates to see how you can use VDOM to create virtual directories. These two activities will show you how to use most of VDOM's methods and properties.

Listing 1, page 44, shows DuplicateVDir, whose algorithm uses VDOM objects to read a virtual directory's properties and print statements to create a VBScript program. When you execute this VBScript program on a different machine, it produces an identical virtual directory. Note two unusual features about Listing 1's code. First, I didn't include the code that parses command-line parameters because it would have added unnecessary complexity to the code and the article. Second, I modified the VB program slightly for readers who don't have access to two machines. Listing 1's code adds the character x to names and paths so that you can test the script with only one machine. The code munges the filenames so that the virtual directory you create doesn't conflict with the existing virtual directory when you run it on the same machine. To create an exact duplicate of a virtual directory, you need to remove this code. Finally, because I added x to the names, when you expand your zip file, you need to modify the names of the directories and files that you created. I noted these areas with comments in the code. Now, let's look at the code.

The first step to duplicating a virtual directory is to create the top-level VDOM object. SQLVDirControl is the only object you need to explicitly create. All other VDOM objects are derived from SQLVDirControl or other objects in VDOM. In the code at callout A in Listing 1, the vdirctl variable holds an instance of SQLVDirControl, which I created by using the New operator. The Connect method connects to the metabase of the IIS server that contains your virtual directory. Although the Connect method lets you specify the name of the IIS server and the Web site number, I accepted the default settings of the current server and the default Web site by choosing to pass no parameters. After VDOM is connected to IIS, you use the SQLVDirs property to obtain a collection of the available SQLXML virtual directories. To access an individual virtual directory, the collection lets you iterate through the items it contains or use an Item property. Callout B shows the code to access the virtual directory named July2002 (the virtual directory I used in "Web Services in Action," July 2002, InstantDoc ID 24910). The callout's code returns a SQLVDir object that represents one virtual directory from the collection. The code then passes the SQLVDir object to the SaveVDir subroutine.

Using the SQLVDir object, the SaveVDir subroutine prints into the VBScript file commands to duplicate the property values on the virtual directory. The properties that SQLVDir exposes correspond closely to the functionality exposed on the MMC's six tabbed dialog boxes. The code at callout C shows that for each property, SaveVDir generates a line of script that sets the property when you create the duplicate virtual directory on the second machine. One property that SaveVDir doesn't set is the password for accessing the database. Because of security concerns, this property is read-only. The code in SaveVDir sets the password to the empty string. If you use the same password on all your machines, you can modify the code to set the appropriate password. Or, you can use the MMC to set the password after you copy the virtual directory to the second machine. Also note that the code doesn't copy the location of the SQLXML Internet Server API (ISAPI) DLL. Setting the location is required only for nonstandard installations where you've relocated the ISAPI DLL. If you customarily install the DLL in another location, add code to the SaveVDir subroutine to set the proper location.

After the SaveVDir subroutine prints code to copy the virtual directory settings, it obtains the collection of virtual names defined within the virtual directory by using the VirtualNames property. Virtual names provide access to templates, annotated schemas, and Microsoft Simple Object Access Protocol (SOAP) methods supported by the virtual directory. The SaveVDir subroutine passes the collection of virtual names to the SaveVNames subroutine. SaveVNames iterates through each virtual name in the collection and prints commands to create identical virtual names in output script. The subroutine uses a VirtualName object, declared as SQLVDIRLib.IVirtualNames, which contains the five properties of the virtual name—Name, Type, Path, WebService, and Domain. Callout D shows the AddVirtualName command that SaveVNames prints for each virtual name in the collection. Use the SoapMethods property to obtain a collection of SOAP methods from the VirtualName object. The SaveVNames subroutine then passes this collection to the SaveSoapMethods subroutine.

The final step in duplicating the virtual directory is to copy the SOAP methods. The soapmeths parameter to the SaveSoapMethods subroutine contains a collection of SoapMethod objects that define the SOAP methods. The code at callout E shows how SaveSoapMethods iterates through the collection, printing AddStoredProcMethod or AddTemplateMethod commands, depending on whether the SOAP method uses a stored procedure or an XML template for its implementation. After SaveSoapMethods prints the commands to create all the methods, it prints calls to GenerateConfig and GenerateWSDL. These methods create the SOAP service configuration (SSC) and Web Services Description Language (WSDL) files that the ISAPI DLL uses when executing SOAP calls. (For an example of how you can use a Web service within an application that uses the SOAP Toolkit, see "Web Services in Action.") After the commands to create the SOAP methods are printed, duplication of the virtual directory is complete.

You can compile the DuplicateVDir program in VB and execute it to produce a script that contains the commands to create a duplicate virtual directory. You can then run this script to create a duplicate virtual directory on your system. You can download the complete VB project, including the code, from http://www.sqlmag.com, InstantDoc ID 25998. Before running the program, duplicate the physical directory structure associated with the virtual directory and make any necessary name changes. Then, execute the VB program to duplicate the virtual directory. You can use MMC to verify the correct operation of the code.

VDOM has proven to be a valuable tool to copy virtual directories between machines in a development environment. You can also use it in your release process to move virtual directory configurations between your development, build, staging, or production servers. Over all, you'll find VDOM a worthwhile utility in your day-to-day development with SQLXML.

From the Blogs

My initial goal in writing this series of posts was to outline some of the concerns surrounding Availability Groups (AGs) and SQL Server Agent Jobs – and call out how there is virtually no guidance from Microsoft on this front and then detail some of the pitfalls and options available for tackling this problem domain. I initially expected this series of posts to have between 25 and 30 posts – according to some of the early outlines I created ‘way back when’....More

Throughout this series of posts I’ve taken a somewhat pessimistic view of how SQL Server Agent jobs are managed within most organizations – meaning that most of the code and examples I’ve provided up until this point were based on assumptions about how CHANGE to jobs is managed. That pessimism, to date, has come in two forms:...More

In this series of posts I’ve called out some of the concerns related to SQL Server AlwaysOn Availability Groups and their interaction with SQL Server Agent jobs – both in the form of Batch Jobs (see post #3) and backups....More