Hey, Scripting Guy! Taking the Express Route
The Microsoft Scripting Guys
In the last few months, one of the Scripting Guys got to experience something new here in the Seattle area. It's a program being tested in various cities throughout the U.S. and it's called electronic tolling. However, in the state of Washington, it's known as Good to Go!
It works something like this: you pay to get an electronic device that attaches to your windshield. You also open an account into which you put a small pile of money. Each time you pass under one of the monitoring devices on the freeway, money is automatically taken from your account. Basically, you're paying to drive on the freeway (so much for the "free" part of freeway—apparently we need to start calling them highways, although we've seen some them under several feet of water recently, which makes them seem not all that high either) without ever having to stop at a toll booth.
Now, in many places where tolls are charged, people who carpool do not have to pay. However, the interesting part about Good to Go! is that it works only in the carpool lane. What's the point of that, you ask? Why would someone go to the trouble of carpooling, then have to pay? Well, they don't. This system only charges people who want to use the carpool lane when they're in their cars by themselves. The obvious reason for wanting to drive in the carpool lane is that there are typically fewer cars in that lane; at times the carpool lane is the only lane where the cars are actually moving.
As we mentioned, this system is experimental right now, though thousands have already signed up for it. There are plenty of people in the Seattle area who are willing to pay money to take an express route to get to wherever it is they're trying to go.
In this month's column, the Scripting Guys have decided to conduct a little experiment of our own. We've decided to show you an express route known as Microsoft® Visual Basic® Express Edition. We'll start off by telling you that one of the coolest things about this route is that it really is free; no tolls will be charged no matter where you use this information, how many people are using it, or what time of day it is. Sounds pretty good, doesn't it? Sure, it may seem like there's a small price to pay in that you have to learn some new things, but you just might decide the benefits are worth it.
Before we go on, we want to mention that we know we're stepping outside our bounds a bit. Typically the Visual Studio® products such as Visual Basic and Visual C#® would be subjects for MSDN® Magazine, not TechNet Magazine. But since MSDN and TechNet seem to be moving more and more toward becoming one big dysfunc—er, happy—family, we're hoping we'll be granted a little leeway here. Also, even though we're talking about working with what has traditionally been a developer tool, we're still talking to Windows® system administrators. Stick with us for a few more minutes and you'll see what we mean.
The first thing you need to do to follow along is install Visual Basic. No, wait. Don't run off saying "I don't have that!" or "I can't afford that!" Microsoft provides an Express Edition of Visual Basic you can download for free from microsoft.com/express/download.
We're not going to go into detail about how to work with Visual Basic Express. There are tutorials in the Help, and the Help itself is actually pretty good. (Hard to believe, isn't it?) What we are going to do is show you how to use Visual Basic Express to solve a particular problem in Windows Vista® (though this example will also work on earlier versions of Windows), and then you can continue to play with it on your own. The problem we're going to solve is this: how do you open a file open dialog box in Windows Vista?
We explained how to open a file open dialog box from a script a few years ago (please see the column "How Can I Show Users a Dialog Box for Selecting Files?" at microsoft.com/technet/scriptcenter/resources/qanda/jan05/hey0128.mspx). That article was published in January 2005, long before Windows Vista came into being. The solution uses the UserAccounts.CommonDialog ActiveX® control to open a file open dialog box, which allows you to browse for a file to open. Unfortunately, this control has been removed from Windows as of Windows Vista, which means this solution won't work on newer systems. (No, no one asked us if this was a good idea.) What this means is that, as far as we know, there is no way to open a file open dialog box using VBScript. So instead of writing a script we're going to use Visual Basic to write an application. One of the things this application will do is open a file open dialog box.
Yes, that's right, the example we're about to show you builds a full application in Visual Basic. That might sound a little scary at first, but you'll see that by using Visual Basic Express, a full application can be as easy to write as a script. This application will consist of a window, or form, that lets you click a button that will open a file open dialog box. You can then select text files from this dialog box, and our application will read from those text files and display a select set of the contents inside the form.
All right, let's get to it. We start by opening Visual Basic Express. The first thing we need to do is to create a new project, which we do by selecting New Project from the File menu. This brings up the New Project dialog box. (Note that if you're using a version of Visual Basic Express earlier than 2008, you'll find a few minor differences from what we present here.) We're going to create a Windows Forms Application, so select the Windows Forms Application template and type in the name you want to give your project. We named ours ReadFiles, as you can see in Figure 1.
Figure 1 Creating a new project in Visual Basic (Click the image for a larger view)
When the project is first created, it automatically provides a new form to work with. The application we're going to create will present a form to the user that looks like the form in Figure 2. As we mentioned, the form includes a button that, when clicked, will display the file open dialog box, open to the C:\Scripts folder. The user will be able to select one or more text files from anywhere in the file system. The application will then read the first line from each of the selected text files and display the results in the listbox in the form. (If this sounds familiar, you most probably participated in the Beginners Division in the 2008 Scripting Games: microsoft.com/technet/scriptcenter/funzone/games/games08/bevent3.mspx.).
Figure 2 The ReadFiles form that will be presented to users
To create our form, we need to drag controls from the Toolbox onto the project form. By default the Toolbox is open on the left side of the Visual Basic window. (If the Toolbox isn't open, click on the Toolbox button on the left side of the Visual Basic workspace and expand All Windows Forms.) Click Button in the Toolbox, then drag the mouse across the form to create the button the size you want. To add a label to the button, click on the button you just added to the form and type the label you want. (Alternatively, you can edit the Text property in the Properties dialog box, by default on the lower-right side of the Visual Basic workspace.) We labeled our button Browse for Files. Next, click ListBox and again click on the form and drag the mouse to create the listbox. We'll use the listbox to display the lines we read from the text files.
That's all we have to do to create our form. Now comes the fun part: we need to make something happen when we click the button. Start by double-clicking the Button control on the form. This will open a code editor with a new subroutine already created for you, the Button1_Click subroutine:
Private Sub Button1_Click _ (ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles Button1.Click End Sub
This sub will run each time the button on our form is clicked. As you can see, this sub is empty at the moment; we need to add the code that will tell the app what to do when the button is clicked. And just what is it we want to do? Well, first we want to do the one thing we promised at the beginning of this column that we'd show you: open a file open dialog box. As with almost everything you're going to do with Visual Basic, we'll use the Microsoft .NET Framework for this.
We start by adding a couple of Imports statements up above the sub:
Imports System Imports System.IO
These statements specify .NET Framework namespaces. We'll be using classes that are in these namespaces, so we import them here so we can simply refer to the classes we want. Note that we said to insert these statements above the sub. Imports statements are global, meaning they can't go inside a subroutine or function; they need to be outside by themselves.
In VBScript, unless you add the Option Explicit statement to the top of your script, you don't need to explicitly declare variables. In Visual Basic, it is automatically added so you need to declare all your variables. We're going to need a variable to hold a reference to the OpenFileDialog object (which just happens to represent the file open dialog box):
Dim dlg As Windows.Forms.OpenFileDialog
Now that we've declared (Dim-ed) a variable of type OpenFileDialog, we can create a new instance of this object, like so:
dlg = New OpenFileDialog()
However, we still haven't displayed the dialog box. First, we need to set some properties:
dlg.Multiselect = True dlg.InitialDirectory = "c:\scripts" dlg.Filter = "txt files (*.txt)|*.txt|" & _ "All files (*.*)|*.*"
The Multiselect property specifies whether the user will be allowed to select more than one file from the file open dialog box. We want them to be able to do this, so we set this property to True. We set the InitialDirectory property to C:\Scripts. If you don't set this property, the dialog box will open to the main computer directory.
And last, but certainly not least, we set the Filter property:
dlg.Filter = "txt files (*.txt)|*.txt|" & _ "All files (*.*)|*.*"
Here we're filtering which files the dialog box will display to the user. We're going to show them only .txt files. Setting these properties will give us a file open dialog box that looks something like Figure 3.
Figure 3 The Open dialog showing only text files (Click the image for a larger view)
Now it's finally time to display the dialog box. We do that with the ShowDialog method:
The ShowDialog method returns a value indicating whether the user clicked Open to open the selected files or clicked Cancel to dismiss the dialog box. If they click Cancel, we don't want to do anything. So we put the call to ShowDialog in an If statement to make sure they've clicked Open before we continue:
If dlg.ShowDialog() = _ Windows.Forms.DialogResult.OK Then
Yes, we know, we checked the OK property rather than the Open property. Behind the scenes, the Open button is really the same as an OK button—it's just that displaying Open to the user makes a lot more sense.
Now we need to know which file or files the user selected from the dialog box. The filenames are contained in the OpenFileDialog object's FileNames property, so we set up a For Each loop to read through the filenames contained in this property:
For Each strName In dlg.FileNames
Oops! We forgot to declare strName:
Dim strName As String
Now we need to open each of these files and read from them. The way we do this in Visual Basic is with a Using block:
Using sr As StreamReader = File.OpenText(strName)
A Using block isn't something that VBScript scripters are used to, since it doesn't actually exist in VBScript. Visual Basic is a little better (OK, in many cases a lot better) at managing system resources than VBScript. The point of a Using statement is to make sure that system resources are freed up when we exit the block. In this case, we're just making sure that we're not hanging on to file contents and large blocks of memory.
We know that this is sounding a little complicated. But really, just look at it like a Set statement. We're simply creating an instance of a new object, in this case a StreamReader object, and assigning it the stream of text returned from the File.OpenText method. Notice that we pass OpenText the name of the file we want to open, the file from our FileNames collection we're currently looping through.
So our StreamReader variable, sr, contains the contents of the file. Now we need another variable:
Dim strLine As String
We'll use this variable to store the first line from the text file we just opened:
strLine = sr.ReadLine()
We read the first line from the file by calling the ReadLine method on our StreamReader object. (Remember that the StreamReader object contains the contents of our file.) We store this line of text in the variable strLine.
Now we simply call the Add method on our ListBox object to add this line to our listbox:
For this example, all we want is the first line of the file, so that we can close our StreamReader—we don't want to hang onto the full text of our text file anymore—and close our Using block:
sr.Close() End Using
After that, we loop around to find the next file that was selected from the file open dialog box until we've read through all the selected files and added all the lines to the listbox. Our completed code looks like Figure 4.
Imports System Imports System.IO Public Class Form1 Private Sub Button1_Click _ (ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles Button1.Click Dim dlg As Windows.Forms.OpenFileDialog Dim strName As String dlg = New OpenFileDialog() dlg.Multiselect = True dlg.InitialDirectory = "c:\scripts" dlg.Filter = "txt files (*.txt)|" & _ "*.txt|All files (*.*)|*.*" If dlg.ShowDialog() = _ Windows.Forms.DialogResult.OK Then For Each strName In dlg.FileNames Using sr As StreamReader = _ File.OpenText(strName) Dim strLine As String strLine = sr.ReadLine() ListBox1.Items.Add(strLine) sr.Close() End Using Next End If End Sub End Class
See, we told you it wasn't much more difficult to create an application than it is to create a script.
You can test your application by pressing F5 (or pressing the Start Debugging button on the Debugging toolbar). When you click on the button and then select one or more files in the file open dialog box, the results should look something like Figure 5.
Figure 5 The first lines of selected files displayed in the listbox
When your application is running just the way you want it to, select Build ReadFiles (or whatever your project name is) from the Build menu. This will create an .exe file named ReadFiles.exe that you can run just like you'd run any other application, and that you can distribute to your users.
We realize this may not have seemed like an "express" route to using the file open dialog box. But when you consider the fact that you can't do this at all by writing a script as of Windows Vista, well, writing a simple application might be a small price to pay. Just like having to pay the money to be able to actually get somewhere when you're on the freeway: it can be a bit of a hassle, but in the end you get where you want to go.
An added advantage to using Visual Basic for something like this is that now you've started working with a tool that's more powerful than VBScript and that allows you to easily create applications with a nice user interface; that's a huge perk right there. System administrators will find plenty of other uses for Visual Basic too.
And remember, you don't need to relearn how to drive to use the new toll lane; you just need to get used to the fact that the cars ahead of you are actually moving. In the same way, if you know VBScript you don't need to learn a completely new language from scratch to use Visual Basic, you just need to get used to the fact that you can do a lot more.
Dr. Scripto's Scripting Perplexer
The monthly challenge that tests not only your puzzle-solving ability but also your scripting skills.
August 2008: Scripting Alphabet
In this month's puzzle, you need to insert the letters A through Z in the blank spaces to reveal a word that relates in some way to scripting. Each letter (A through Z) should be used only once, and the letters do not appear in alphabetical order. The inserted letter could be the beginning of the word, the end of the word, or anywhere in the middle of the word. For example, in the first line we've inserted the letter C to complete the word SCRIPT:
The Scripting Guys work for—well, are employed by—Microsoft. When not playing/coaching/watching baseball (and various other activities) they run the TechNet Script Center. Check it out at www.scriptingguys.com.
© 2008 Microsoft Corporation and CMP Media, LLC. All rights reserved; reproduction in part or in whole without permission is prohibited.