Hey, Scripting Guy! How Can I Create an HTA For Displaying Log Files?

Hey, Scripting Guy! Question

Hey, Scripting Guy! I have a bunch of log files (all in the same folder) that I periodically need to review. What I thought would be really cool would be to have an HTA that, when it starts up, retrieves all the log file names and displays those names in a list box; I could then click any file name and the HTA would read the file and display the contents in a text box. However, I have no idea how to do anything like that. Can you help me out here?

-- JJ

SpacerHey, Scripting Guy! AnswerScript Center

Hey, JJ. You know, in recent years there has been a lot of hue and cry over the fact that people are reading far less than they used to. For example, in 1950 the average household in the US bought – and read – 1.23 newspapers per day. (In other words, many people subscribed to more than one newspaper.) Today that number has dropped to about .44 newspapers today, meaning that most people don’t subscribe to any newspaper. Magazines have suffered a similar decline, and nowadays only about half of all Americans read even a single book during the course of a year.

In fact, according to media experts, the world is now down to just one thing that people absolutely have to read each time it comes out: the official Winter Scripting Games program.

Note. OK, maybe there are two things. But we aren’t convinced that anyone actually reads the annual Sports Illustrated swimsuit issue.

Statistically speaking, it’s possible that some you are included in that cohort of people who read only one thing – the Scripting Games program – during the course of a year. (Of course, if that is the only thing you read all year, well, then you’re probably not reading today’s column, are you?) Either way we have good news for you: the 2008 Winter Scripting Games program is out and available for downloading. (In case you’re wondering, a 3-megabyte .PDF file.)

Now, do you have to download a copy of the program in order to enter the Scripting Games? Of course not; we wouldn’t do that to you. (Well, we would, but seeing as how we can’t charge you for the program, well, what’s the point?) Nevertheless, you might find the information in the program to be useful, especially if you haven’t competed in the Games before; after all the program’s FAQ will give you a good idea what to expect when the Games actually begin on February 15th. In addition, the program includes a complete schedule of events (including all the deadlines); an overview of some of the new features of the 2008 Scripting Games (including the User Group, International, and Sudden Death challenges); and a brief description of all the events, in both the Beginners and the Advanced Division. If you’ve been wondering what sorts of things you’ll be asked to do in the 2008 Games, well, the program should give you a hint or two.

Heck, there’s even a scripting languages trivia test. Why was Windows PowerShell originally known as Monad? You’ll find the answer to that – and the rest of life’s burning questions – in the program.

We should also add that downloading the program is also a nice way to show our sponsors that you care. This year we have some absolutely incredible prizes donated by companies like Sapien Technologies, Special Operations Software, and Shell Tools. We want them to understand how much we appreciate their generosity.

And, needless to say, we’re hoping they’ll be willing to chip in for the 2009 Games as well.

At any rate, if you are the type of person who reads only one thing a year, well, you’re free to go and download the program; thanks for dropping by. For those of you who read at least two things a year, however, we’ll go ahead and show you how to create an HTML Application (HTA) that can retrieve a list of all the files in a folder and then, any time you click on one of those files, display the contents of that file in a text box in the HTA.

As a matter of fact, this is how you can create an HTA like that:

<SCRIPT Language="VBScript">   

   Sub Window_Onload       

      strComputer = "."       

      Set objWMIService = GetObject("winmgmts:\" & strComputer & "rootcimv2")       

      Set colFiles = objWMIService.ExecQuery ("ASSOCIATORS OF {Win32_Directory.Name='C:Scripts'} Where "  & "ResultClass = CIM_DataFile")       

      For Each objFile In colFiles           

         Set objOption = Document.createElement("OPTION")           

         objOption.Text = objFile.FileName           

         objOption.Value = objFile.Name           



   End Sub   


   Sub ReadFile       

      Set objFSO = CreateObject("Scripting.FileSystemObject")       

      Set objFile = objFSO.OpenTextFile(LogFiles.Value)       

      strContents = objFile.ReadAll       


      LogContents.Value = strContents   

   End Sub




   <table width="100%">       


         <td width="25%" valign="top">

            <select size="35" name="LogFiles" onChange="ReadFile" style="width:150px"></select></td>           

         <td width="75%" valign="top">

            <textarea name="LogContents" rows="35" cols="100"></textarea></td>       




Let’s start off by taking a look at the body of our HTA. As you can see, the body consists entirely of a two-column, one-row table. Why did we use a table here? One reason and one reason only: that makes it very easy for us to place our list box and our text box (or, more correctly, our textarea) side-by-side. We put the list box in column 1 of the table, using this bit of HTML tagging to define the list box:

<select size="35" name="LogFiles" onChange="ReadFile" style="width:150px"></select>

As you can see, this is a simple little list box, one with a size of 35 (that is, 35 items will appear onscreen at a time) and the name LogFiles. We’ve also added two additional parameters to the list box: onChange="ReadFile", which simply tells the HTA that it should run the subroutine ReadFile any time the value in the list box changes; and style="width:150px" which simply sets the width of our list box to 150 pixels.

Like we said, a simple little list box. So simple, in fact, that we haven’t even defined any options for the thing. But don’t worry; we’ll take care of that in a few minutes.

Before we do that, however, we need to use this line of code to add a textarea to the HTA:

<textarea name="LogContents" rows="35" cols="100"></textarea>

Again, there’s nothing fancy here. We have a textarea named LogContents, a text area designed to show 35 rows and 100 columns. (In HTML, a “column” in a text area is approximately equal to a single character. Thus we’re displaying 100 characters or so in each line in the text box.)

That takes cares of the body of the HTA. Now let’s tackle our two subroutines: Window_OnLoad and ReadFile.

As many of your know, in an HTA a subroutine named Window_OnLoad automatically runs any time that HTA is loaded or refreshed. So what are we asking our HTA to do any time it loads or refreshes? Well, for starters, we’re asking it to connect to the WMI service on the local computer and then use this line of code to retrieve a collection of all the files in the folder C:Scripts:

Set colFiles = objWMIService.ExecQuery("ASSOCIATORS OF {Win32_Directory.Name='C:Scripts'} Where " & "ResultClass = CIM_DataFile")

Now we’re going to add some options to our list box; more specifically, we’re going to add the files in C:Scripts to the list box. To that end, we first set up a For Each loop to loop us through the collection of files:

For Each objFile In colFiles

Inside the loop we use this line of code to create a “blank” option for the list box:

Set objOption = Document.createElement("OPTION")

After that we assign values to two properties of our new option: we set the value of the Text property to the name of the first file in our collection (in WMI-speak, that’s the FileName property), and we set the option’s Value property to the file path (WMI’s Name property). That means that only the name of the file (e.g., IIS Log) will appear in the list box. However, when a user clicks on the box the complete file path will be retrieve, making it easy for us to locate and open the file.

At that point all we have to do is call the Add method to add this new option to the LogFiles list box:


And then it’s back to the top of the loop, where we repeat the process with the next file in the collection. When all is said and done, the file name of each file in C:Scripts will appear as an option in the LogFiles list box.

Now, what about the ReadFile subroutine? Well, as we noted earlier, each time the user selects an item in the list box the ReadFile subroutine gets called. When that happens, we’re going to create an instance of the Scripting.FileSystemObject, then use this line of code to open the text file that the user selected:

Set objFile = objFSO.OpenTextFile(LogFiles.Value)

Once the file is open, we use the ReadAll method to read the entire contents of the file into a variable named strContents; we then close the text file. And what do we do with strContents? Why, we assign that value to the Value property of our textarea:

LogContents.Value = strContents

As you might expect, that’s going to cause the contents of the selected text file to magically appear in the textarea. Here’s a somewhat-scrunched-up picture of what that might look like:


Click another file in the list box and the contents of that file will be displayed in the textarea. It’s pretty cool, and it’s way faster than manually opening all these files.

That should do it, JJ. Remember, this is going to work only with text files; you’re not going to display an Excel spreadsheet or a PowerPoint slide presentation in an HTA. (That would be cool, but it’s not going to work.) But that’s no big deal; after all, in this day and age no one’s going to read that Excel spreadsheet or PowerPoint presentation anyway.

Especially now that the Scripting Games program is out.

Comments (1)

  1. Daryl says:

    How would you modify this if you have other files in the same directory but only want to use those with a .log extension?

Skip to main content