Open (Well, File Open) Sesame

Posted by Greg Stemp. I guess if you walk around calling yourself a Microsoft Scripting Guy then you shouldn’t be surprised when people ask you scripting questions all the time. What’s interesting, though, is how many people ask me other types of computer questions; I think there’s this (mistaken) assumption that if you work at Microsoft you must know everything there is to know about computers. The truth is, what little expertise I have in computers lies in a very esoteric area: system administration scripting. I try to explain that to people, and yet they still ask me how they can change the paper size in Greeting Card Designer, or want to know why it takes so long to export pictures from their digital camera. And if I try to tell them I don’t have any idea, they think I just don’t want to help them. I once had a lady ask me if I could fix her electric typewriter (!), I guess because a typewriter is vaguely related to a computer.

Digression: The best computer question I was ever asked happened when I worked at the University of Washington. One of the secretaries stopped me in the hall and said she had to do a budget spreadsheet, and she wanted to know if her copy of Excel was still good. I told her that it should be, and asked why she wanted to know. “Oh, I haven’t used it in several months, and I just didn’t know if those things got rusty or something if you didn’t use them.” True story.

Anyway, no one ever asks me things like which team I think will win the NCAA men’s basketball tournament (I picked Stanford at the start of the year, and I’m sticking with them for the time being). And no one ever asks me what are the five greatest TV shows of all time. But now that I have a blog at my disposal, I can answer that question without being asked:

  1. The Simpsons. Yes, I realize that their glory days are behind them. Still, watch the episode where Homer and Apu go to India, and then try and tell me this isn’t the best show of all time. The only question that remains is this: Which is the best Simpsons’ episode ever? I say it’s the Sherry Bobbins one; my son holds out for the softball episode. But we’ll go with Sherry Bobbins. When he gets his own blog, he can name whatever episode he wants as No. 1.
  2. Mystery Science Theater 3000. This thing got bounced around on a number of minor cable networks and through innumerable timeslots before finally coming to an end. I never understood that. What, ABC and NBC have so many great shows packed into their weekly schedule that they couldn’t find room for MST3K? While I didn’t go so far as to name my son Crow T. Robot, the computer I’m typing on right now is named TomServo.
  3. Pete and Pete. This was a show that ran on Nickleodeon for a few years, and has never been seen since. (Which is weird; I mean, Nickleodeon typically shows the same episode of Spongebob SquarePants or The Fairly OddParents three or four times a day every day of the year.) A true classic, even if I am the only person in the world who appreciated it.
  4. Futurama. Another Matt Groening production, and gone before its time. Did you ever see the episode when the whole crew logged onto the Internet? Or the visit to the Slurm factory? How about the lucky clover? What, are you guys wasting your time reading or exercising or spending quality moments with your family? You need to stay in and watch more TV.
  5. Baseball Tonight. Ok, this doesn’t really fit with the other shows on the list. But it’s not unusual, during the season, for my son and I to watch this twice a night. And both of us think Buck Showalter is a better analyst than he is a manager.

Oh, well; I guess I better throw some scripting stuff in here, hadn’t I? Here’s some information that I’ve had lying around on my computer for months, and finally found again. Last summer someone asked me if there was any way to call the File Open dialog box from within a script. I told him that there was, and that, in fact, I had a script somewhere that showed how to do this. Naturally, then, I could never find that script, and could never remember where I had learned about this method in the first place. And then, a week or so ago, I was cleaning out my office, and there it was. A bit late for the guy who asked me about it, but ….

This dialog box is actually used in the User Accounts control panel (Nusrmgr.cpl) found in Windows XP (and if you’re wondering, yes, that means that it only works under Windows XP). It’s a real-live File Open dialog box, with just one real limitation: it’s best for selecting a single file at a time (it’s possible to create a multi-select dialog box, but it’s a bit different in appearance, and a bit goofy to use). Let’s take a look at code which calls the dialog box; we’ll then explain what the code is doing, and clue you in on a few optional property values you can use as well. Here’s the basic code:

Set objDialog = CreateObject("UserAccounts.CommonDialog")

intResult = objDialog.ShowOpen

If intResult = 0 Then

    Wscript.Quit

Else

    Wscript.Echo objDialog.FileName

End If

Pretty simple stuff. You create an instance of the UserAccounts.CommonDialog object, and you then call the ShowOpen method to display the dialog box.

What happens next depends on what the user does. Suppose the user clicks the Cancel button. In that case, ShowOpen returns a 0, and – in our case – the script quits. If the user selects a file and then clicks Open, ShowOpen returns two things: a 1, which simply indicates that the Open button was clicked; and the full path to the name of the selected file (for example, C:\Scripts\MyScript.vbs). Now, in our little demonstration script above, we simply echo the name of that file. In a real script, of course, you might pass that file name to the WSH Run method, you might delete that file, you might do, well, whatever you want. The important thing is that you were able to get a pointer to that file without the user (or) you having to type anything in.

Try the script above and you’ll see what I mean.

In addition to the basic model, there are a number of properties you can include when opening this dialog box. We’re not going to bother going through all of them today; I’ll either address them in a later posting or, more, likely, I’ll do a more extensive Scripting Clinic article on this. But here are the more useful object properties you can set if you so desire:

Filter. Suppose you’re in Word and you click the File Open button; as you might expect, the File Open dialog box appears (and to think some people are critical of Word!). At the bottom of the dialog box you’ll see a dropdown list titled Files of Type, a list that, by default, reads something like All Word Documents (*.doc; .dot; *.htm; *.html; *.url) , etc.. If you’d rather filter the list, you can click the dropdown and select something like Word Documents (*.doc) . In that case, the only files that will appear in the dialog box are those with a .doc file extension.

Can you apply a filter to your dialog box? You bet you can. For example, to show only .vbs files, set the filter to this:

objDialog.Filter = "VBScript Scripts|*.vbs|"

Note that the filter consists of three parts:

  • A text description (VBScript Scripts).
  • The pipe separator (|).
  • The actual filter itself (*.vbs).

Suppose you wanted to give people the option of viewing both .vbs and .js files. Then use syntax similar to this, separating the file extension wildcards with a semi-colon:

objDialog.Filter = "Scripts|*.vbs;*.js|"

And finally, what if you wanted to give them the ability to see different sets of files (that is, what if you’d like to give them some choices in the Files of Type dropdown)? Again, no problem: just include multiple filters when setting the Filter value, taking care to separate individual filters with the pipe separator:

objDialog.Filter = "VBScript Scripts|*.vbs|All Files|*.*"

FilterIndex. By default, the dialog box will filter file names based on the first item in your set of Filters. In our previous example, VBScript Scripts will be the default, because it comes first in the list. To view all files, you’ll have to click the dropdown list and select All Files. But suppose you’d rather have All Files as the default. Well, you could either swap places with VBScript Scripts when assigning the Filter value, or you could set the FilterIndex to 2. Why 2? Because All Files is the second item in the list. What if you add a third filter and want that as the default? Ah, you’re way ahead of me: just set the FilterIndex to 3.

InitialDir. By default, when you call the File Open dialog box, it starts up in the same folder as the script that called it. What if you’d like it to start up in a different folder? No problem; just set InitialDir to the desired folder (for example, InitialDir = “C:\My Files”). If the folder doesn’t exist, the dialog box will revert to its default behavior and start up in the same folder as the script that called it.

Here’s a more full-featured script that uses all these properties:

Set objDialog = CreateObject("UserAccounts.CommonDialog")

objDialog.Filter = "VBScript Scripts|*.vbs|All Files|*.*"

objDialog.FilterIndex = 1

objDialog.InitialDir = "C:\Scripts"

intResult = objDialog.ShowOpen

If intResult = 0 Then

    Wscript.Quit

Else

    Wscript.Echo objDialog.FileName

End If

Cool, huh? Of course, now you’re probably thinking, “Hey, if there’s a File Open dialog box we can use, does that mean there’s also a File Save dialog box we can use?” You bet there is, but to learn about that you’ll have to come back tomorrow. (Yes, I know that’s unfair, but that’s life. Or at least the part of life the deals with blogs).