The ABCs of HTAs: Scripting HTML Applications

HTAs

Use a File Open Dialog Box to Populate a List Box (Windows XP-only)

One bit of functionality found in a lot of HTAs (at least HTAs written by system administrators) is this: you select a text file containing computer names, then your script opens that text file and auto-populates a list box with those names. You can then run code against any one of those computers merely by selecting the name from the list box and, say, clicking a Run Script button.

That’s a great use of HTAs and we definitely recommend it: it’s better to read names in from a text file (or an Active Directory container) and create a list box on-the-fly as opposed to hard-coding that list box into the HTA itself. (Why? Because it’s easier to add or subtract names from a text file than it is to add or subtract options from HTA code.)

The only problem is this: if you have numerous text files containing computer names (one with all your mail servers, one with all your workstations, one with all your DNS servers), how do you know which file to open? Typically people rely on VBScript’s InputBox function when it comes to specifying a particular text file; they use InputBox to display a dialog box like this and then ask people to type the path name to the file:

Input Box

There isn’t really anything wrong with this; however, it does require people to know the exact path to the text file and to type that path name in correctly. Wouldn’t it be cool if you could display a real, live File Open dialog box that they could use to locate and select a file:

File Open Dialog Box

Well, guess what? As long as you’re running Windows XP (sorry, this technique won’t work on any other operating system) you can do just that. And we’re here to tell you how.

Here’s a script that pops up a File Open dialog box, lets you select a file, then opens that text file and adds each computer name to a list box named AvailableComputers:

<html>
<head>
<title>Load Computers Sample</title>
<HTA:APPLICATION 
     ID="objTestHTA"
     APPLICATIONNAME="Load Computers Sample"
     SCROLL="yes"
     SINGLEINSTANCE="yes"
     WINDOWSTATE="maximize"
>
</head>

<SCRIPT Language="VBScript">

Sub LoadComputers

    Set objDialog = CreateObject("UserAccounts.CommonDialog")
    objDialog.Filter = "Text Files|*.txt|All Files|*.*"
    objDialog.FilterIndex = 1
    objDialog.InitialDir = "C:\Scripts"
    intResult = objDialog.ShowOpen

    If intResult = 0 Then
        Exit Sub
    End If

    For Each objOption in AvailableComputers.Options
        objOption.RemoveNode
    Next
    
    ForReading = 1
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    Set objFile = objFSO.OpenTextFile _
        (objDialog.FileName, ForReading)
    Do Until objFile.AtEndOfStream
        strLine = objFile.ReadLine
        Set objOption = Document.createElement("OPTION")
        objOption.Text = strLine
        objOption.Value = strLine
        AvailableComputers.Add(objOption)
    Loop
    objFile.Close

End Sub

</SCRIPT>

<body bgcolor="buttonface">
<input id=runbutton  class="button" type="button" value="Load Computers" 
name="run_button"  onClick="LoadComputers"><p>

<select size="10" name="AvailableComputers" style="width:300" >
</select>

</body>
</html>

When you run this script your list box should end up looking something like this:

Computer List

So how does this all work? Well, all the excitement occurs inside a subroutine named LoadComputers. That subroutine does three things:

  • Displays the File Open dialog box and determines the name of the file you selected. (Or exits the subroutine if you clicked Cancel instead.)

  • Removes any options currently in the AvailableComputers list box.

  • Reads the text file and adds each computer as an option to the list box.

Let’s take a look at each step in the process.

Step 1: Using the File Open Dialog Box

Here’s the code that actually displays the File Open dialog box:

Set objDialog = CreateObject("UserAccounts.CommonDialog")
objDialog.Filter = "Text Files|*.txt|All Files|*.*"
objDialog.FilterIndex = 1
objDialog.InitialDir = "C:\Scripts"
intResult = objDialog.ShowOpen

If intResult = 0 Then
    Exit Sub
End If

We won’t explain the code in any great detail here; for an explanation of the dialog box properties take a look at this Hey, Scripting Guy! column. For now we’ll simply note two things. First, our dialog box is an instance of the UserAccounts.CommonDialog object and is given the object reference objDialog; later on we’ll use the FileName property of this object to determine the path to the selected text file. Second, after configuring the dialog box properties we use the ShowOpen method to display the dialog box.

So what happens then? Well, at that point we wait for the user to select a file and click the OK button (or to click the Cancel button). How do we know which button was clicked? Well, when the dialog box is dismissed the return value is captured in a variable named intResult. If intResult is 0, that means the user clicked Cancel; thus we exit the subroutine. If intResult is anything but 0 that means the user selected a file and clicked OK. As a result, we proceed with the second portion of the subroutine. In other words:

If intResult = 0 Then
    Exit Sub
End If

Step 2: Removing Existing Options

If you click the Load Computers button you’ll eventually load a bunch of computer names into the AvailableComputers list box. Now, what happens if you click Load Computers a second time, to load in a different set of computer names? Well, one thing that should happen is that we get rid of the first set of computer names; in other words, we need to clear the list box before we re-populate it. Here’s the code that clears the list box:

For Each objOption in AvailableComputers.Options
    objOption.RemoveNode
Next

All we’re doing here is creating a For Each loop that cycles through all the options (all the items) in the list box. For each option we find we call the RemoveNode method to remove that option from the list box. By the time the loop is complete we’ll have found and removed each item in the list box.

Step 3: Reading the Text File and Adding Options

Now all we have to do is grab the computer names and stash them in the list box. Here’s the code that does that:

ForReading = 1
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile _
    (objDialog.FileName, ForReading)
Do Until objFile.AtEndOfStream
    strLine = objFile.ReadLine
    Set objOption = Document.createElement("OPTION")
    objOption.Text = strLine
    objOption.Value = strLine
    AvailableComputers.Add(objOption)
Loop
objFile.Close

What we do here is create an instance of the FileSystemObject and then open the text file selected by the user; the path to that file is stored in the FileName property of the File Open dialog box. We open the text file and read in the first line, which just happens to correspond to the name of the first computer in the list. (We’re assuming that each line in the file is the name of one – and only one – computer.)

As soon as we get the computer name we can start populating the list box. We do that with these four lines of code:

Set objOption = Document.createElement("OPTION")
objOption.Text = strLine
objOption.Value = strLine
AvailableComputers.Add(objOption)

We begin by creating an instance of the Option object; we then set both the Text and Value properties to strLine (that’s the variable containing the computer name). After configuring those two properties we call the Add method to add the option to the AvailableComputers list box. We then loop around and repeat the process until each line in the file has been read.

There you have it: not only have we created an on-the-fly list box, but we did it using a cool File Open dialog box to boot. Life truly is beautiful!