November 1st, 2004

How Can I Make Selections from a Form When Using a Script?

Hey, Scripting Guy! Question

Hey, Scripting Guy! I’d like to have a form with four radio buttons on it, each button representing a different computer. You choose a radio button, click another button, and then a script runs against the computer you selected. How do I do that?

— CW

SpacerHey, Scripting Guy! AnswerScript Center

Hey, CW. If we’re talking strictly VBScript and Windows Script Host, the answer is simple: you don’t. Other than displaying a message box, neither VBScript nor WSH have the ability to create graphical user interfaces; there’s no way to use radio buttons, list boxes, dropdown lists, and other graphical elements from within a script.

But – oh, you must have seen this episode before. That’s right: first we tell you that something can’t be done, and then we tell you a way to do it anyway. (Hey, everyone needs a gimmick, right?) And you’re right: while you’re not going to do this using only VBScript, you definitely can do this using an HTA (HTML Application).

We won’t spend much time talking about HTAs today; if you’re interested, you might check out a Webcast we did on this topic about a year ago. Suffice to say that HTAs allow us to combine Internet Explorer and scripting code and, in turn, give our scripts a graphical user interface. And while there are other ways to incorporate a graphical user interface into your scripts, this is probably the easiest for those of you just starting out with GUI development.

Let’s start by giving you the code for the HTA, and then we’ll explain how it all works. This sample HTA displays four radio buttons, each representing a different computer. You select a computer and click a Run Script button; when you do, a subroutine will run that goes out, connects to the chosen computer, and then reports back the name of the operating system installed on that computer. Cool, huh? To see how this works, copy the code, paste it into Notepad, and then save the file with a .hta file extension (for example, os_name.hta). Don’t use a .vbs file extension; that won’t work. It must be .hta.

<SCRIPT LANGUAGE=”VBScript”>

Sub RunScript

If ComputerOption(0).Checked Then strComputer = ComputerOption(0).Value End If If ComputerOption(1).Checked Then strComputer = ComputerOption(1).Value End If If ComputerOption(2).Checked Then strComputer = ComputerOption(2).Value End If If ComputerOption(3).Checked Then strComputer = ComputerOption(3).Value End If

If strComputer = “” Then Exit Sub End If

Set objWMIService = GetObject _ (“winmgmts:\\” & strComputer & “\root\cimv2”) Set colItems = objWMIService.ExecQuery _ (“Select * From Win32_OperatingSystem”) For Each objItem in ColItems Msgbox objItem.Caption Next

End Sub

Sub CancelScript Self.Close() End Sub

</SCRIPT>

<BODY> <input type=”radio” name=”ComputerOption” value=”atl-ws-01″>atl-ws-01<BR> <input type=”radio” name=”ComputerOption” value=”atl-ws-02″>atl-ws-02<BR> <input type=”radio” name=”ComputerOption” value=”atl-ws-03″>atl-ws-03<BR> <input type=”radio” name=”ComputerOption” value=”atl-ws-04″>atl-ws-04<P>

<input id=runbutton class=”button” type=”button” value=”Run Script” name=”ok_button” onClick=”RunScript”> &nbsp;&nbsp;&nbsp; <input id=runbutton class=”button” type=”button” value=”Cancel” name=”cancel_button” onClick=”CancelScript”>

</BODY>

So what do we have here? We can break this code down into four sections: two that use HTML tags to display the radio buttons and Run Script and Cancel buttons, and two others to run subroutines depending on whether you click Run Script or Cancel. Let’s take a closer look at each of these sections.

Here, for example, is the HTML code which displays the four radio buttons. (If you know HTML, there’s nothing special here; this is standard HTML coding.) Note that all the buttons have the same name (ComputerOption); that’s required to ensure that you can only select one button at a time. Note, too that the Value for each button is set to the name of the computer:

<BODY>
<input type=”radio” name=”ComputerOption” value=”atl-ws-01″>atl-ws-01<BR>
<input type=”radio” name=”ComputerOption” value=”atl-ws-02″>atl-ws-02<BR>
<input type=”radio” name=”ComputerOption” value=”atl-ws-03″>atl-ws-03<BR>
<input type=”radio” name=”ComputerOption” value=”atl-ws-04″>atl-ws-04<P>

And here is the code that displays the Run Script and Cancel buttons. The key here is the onClick parameter, which indicates which subroutine will run when a button is clicked. As you can see when you click the first button, the subroutine RunScript runs; click the second button and the subroutine CancelScript runs:

<input id=runbutton class=”button” type=”button” value=”Run Script” name=”ok_button” 
onClick=”RunScript”>
&nbsp;&nbsp;&nbsp;
<input id=runbutton class=”button” type=”button” value=”Cancel” name=”cancel_button” 
onClick=”CancelScript”>

</BODY>

The CancelScript subroutine, by the way, simply closes the HTA. As you can see, not a terribly-complicated procedure by any means:

Sub CancelScript
   Self.Close()
End Sub

Now – at last! – we get to the good stuff. You select a radio button, and then click Run Script. How does our HTA know which button you selected, and how does it know which computer to run the script against? For that matter, where the heck is the script we want to run? Relax; everything is here in the RunScript routine:

Sub RunScript

If ComputerOption(0).Checked Then strComputer = ComputerOption(0).Value End If If ComputerOption(1).Checked Then strComputer = ComputerOption(1).Value End If If ComputerOption(2).Checked Then strComputer = ComputerOption(2).Value End If If ComputerOption(3).Checked Then strComputer = ComputerOption(3).Value End If

If strComputer = “” Then Exit Sub End If

Set objWMIService = GetObject _ (“winmgmts:\\” & strComputer & “\root\cimv2”) Set colItems = objWMIService.ExecQuery _ (“Select * From Win32_OperatingSystem”) For Each objItem in ColItems Msgbox objItem.Caption Next

End Sub

The first half of this subroutine determines which button you selected. Radio buttons (at least those with the same name) are stored as an array; the first button in the array is item 0, the second button in the array is item 1, etc. What we do here is determine which button was selected; that’s done by looking at the Checked property for each button. For example, this line of code looks to see if the Checked property of button 0 (the first button in the array) is true; if it is, that means this was the button that was selected:

If ComputerOption(0).Checked Then

And what happens if Checked is true? Well, then we assign the value of the radio button (and remember, the value of the button happens to be the name of a computer) to the variable strComputer:

strComputer = ComputerOption(0).Value

And what happens if Checked is False? No big deal; after all, we check the value of each radio button. Sooner or later we’ll find out which button was selected (and there can only be one). If it turns out that none of the buttons were selected, then we simply exit the subroutine. That’s what this code does:

If strComputer = “” Then
    Exit Sub
End If

If a button was selected, then strComputer will be equal to the name of the computer we want to connect to. And that’s what the second half of this subroutine does: it’s a standard WMI script that connects to the specified computer and returns the name of the operating system that’s installed.

Whew! We’re bet you’re glad that’s done, aren’t you? Or at least you would be if we were actually done. But there’s one other point we need to make. The sample HTA we showed you here retrieves the name of the operating system installed on a computer, and then displays that name in a message box. That’s fine, but what if you wanted to display, say, a list of all the services installed on a computer? In that case, you’d find yourself responding to scores of message boxes, which is probably not the user experience you’re we’re hoping for.

So can we fix that? Of course. We don’t want to spend much more time on this, but we need to do a few things. First, we have add a SPAN area to our HTA; this is simply an identifiable area on the screen where we can write information. Use code like this to put a SPAN (with the ID of DataArea) beneath all your buttons:

<P>
<span id=DataArea></span>

Second, instead of displaying all the data in a message box, we need to gather up that data and store it all in a variable. This code sets the value of the variable strText to anything that’s currently in strText plus the value of the caption property plus the <BR> tag (which is the HTML equivalent of hitting the ENTER key on the keyboard):

strText = strText & objItem.Caption & “<BR>”

Finally, we need to set the InnerHTML property of our SPAN to the value of the variable strText:

DataArea.InnerHTML = strText

Got all that? Again, without bothering to go into much explanation, here’s a revised HTA which gathers the names of all the services installed on a computer, and then writes those names in the HTA itself:

<SCRIPT LANGUAGE=”VBScript”>

Sub RunScript

If ComputerOption(0).Checked Then strComputer = ComputerOption(0).Value End If If ComputerOption(1).Checked Then strComputer = ComputerOption(1).Value End If If ComputerOption(2).Checked Then strComputer = ComputerOption(2).Value End If If ComputerOption(3).Checked Then strComputer = ComputerOption(3).Value End If

If strComputer = “” Then Exit Sub End If

Set objWMIService = GetObject _ (“winmgmts:\\” & strComputer & “\root\cimv2”) Set colItems = objWMIService.ExecQuery _ (“Select * From Win32_Service”) For Each objItem in ColItems strText = strText & objItem.Name & “<BR>” Next

DataArea.InnerHTML = strText

End Sub

Sub CancelScript Self.Close() End Sub

</SCRIPT>

<BODY> <input type=”radio” name=”ComputerOption” value=”atl-ws-01″>atl-ws-01<BR> <input type=”radio” name=”ComputerOption” value=”atl-ws-02″>atl-ws-02<BR> <input type=”radio” name=”ComputerOption” value=”atl-ws-03″>atl-ws-03<BR> <input type=”radio” name=”ComputerOption” value=”atl-ws-04″>atl-ws-04<P>

<input id=runbutton class=”button” type=”button” value=”Run Script” name=”ok_button” onClick=”RunScript”> &nbsp;&nbsp;&nbsp; <input id=runbutton class=”button” type=”button” value=”Cancel” name=”cancel_button” onClick=”CancelScript”> <P> <span id=DataArea></span> </BODY>


Author

0 comments

Discussion are closed.