The point of scripting is that instead of using a canned application to perform a certain task, you can easily and quickly throw together a script that does exactly what you need. That said, you may need some inspiration to get you cooking.
The following examples use many of the custom subroutines and functions outlined earlier in this book, but for brevity and sanity, they won't be repeated in the forthcoming snippets of code.
The script in Example 9-2 starts by prompting you for the name of a folder to back up and checks to see if it exists. If not, it gives you an opportunity either to type another folder name or exit. Once a valid folder name has been entered, the script creates a backup of the entire folder on your floppy drive.
On Error Resume Next Accepted = False Do Until Accepted MyFolder = InputBox("Please enter the name of the folder _ you want to back up.") If Not FolderExists(MyFolder) Then Answer = MsgBox("The folder you typed doesn't exist. _ Try again?", 36, "") If Answer = 7 Then WScript.Quit Else Accepted = True End If Loop Answer = MsgBox("Please put a diskette in your floppy drive.", 33, "") If FolderSize(MyFolder) > DriveFreeSpace("a") Then MsgBox "The folder you specified won't fit on the floppy.", 16 WScript.Quit End If If FolderCreate("a:\Backup\") = False Then MsgBox "There was a problem writing to the diskette.", 16 WScript.Quit End If Call FolderCopy(MyFolder, "a:\Backup\") If Right(MyFolder, 1) <> "\" Then MyFolder = MyFolder & "\" Call WriteToFile(MyFolder & "backuplog.txt", _ "Last backed up: " & Now)
This script uses several MsgBox prompts and, if used unaltered, will probably irritate most users. (Hint: think about who will be using the scripts you write when you decide how much error checking and prompting is appropriate.) However, it also shows part of the power of interactive scripting. A little intelligent planning and error trapping can keep your scripts running smoothly, interrupting you only when necessary. Note the use of the FolderExists function at the beginning of the script; rather than risking encountering an error, the script checks for a potential problem (a missing file) and then takes the necessary steps to resolve it. Note also that if the folder doesn't exist and the user doesn't want to try again, the user can exit; always give your users a choice to get out if they want.
Because we have implemented some degree of error checking in this script, we include the line On Error Resume Next at the beginning of the script. This statement instructs WSH to simply ignore any errors it finds. This doesn't automatically resolve any errors; it just eliminates the error message that would otherwise appear in the event of an error, allowing the script to continue uninterrupted. This way, we're only bothered with the errors that concern us.
This example also uses the Do...Loop loop structure (which is similar to the For...Next loop, documented earlier in this chapter) at the beginning of the script. The code inside such a loop is repeated until a specific condition is met; in this case, the loop will repeat until the Accepted variable has a value of True (notice that it's set to False at the beginning of the script). The If...Then structures insure that the Accepted variable is only set to True if the folder actually exists.
The second part of the script compares the total size of the folder and all its contents with the amount of free space on the diskette currently inserted in the floppy drive. You could expand the script, so that if the diskette is not sufficient to store the folder, the user is given the opportunity to insert another diskette and try again. You'd need to use a similar Do...Loop, as described earlier.
Once the script has gone through all of the tests (eliminating the possibility of many errors), the FolderCopy subroutine is used to copy the folder to the floppy. Finally, the WriteToFile subroutine is used to record in a log file that the folder was backed up. Note also the preceding line that adds a backslash ( \) to the end of the MyFolder variable; this way, we can pass a valid filename (the folder name followed by a backslash and then the filename) to the WriteToFile subroutine.
This script requires the following subroutines, which are found earlier in this book: DriveFreeSpace, FolderCopy, FolderCreate, FolderExists, FolderSize, and WriteToFile.
Nothing exemplifies the power of the Internet more than an Internet-enabled fishtank. This, essentially, is a web page with a dynamic picture of the contents of a fishtank. There are several ways to do this, but the following shows that it can be done with nothing more than a script, a camera, and a common FTP account.
These listings assume that all files are stored in the folder c:\camera. Start with the script shown in Example 9-3.
On Error Resume Next ImageFile = "c:\camera\fish.jpg" Call FileDelete(ImageFile) Call RunProgram("c:\camera\camera.exe " & ImageFile, True) If Not FileExists(ImageFile) Then WScript.Quit Call RunProgram ("ftp -n -s:c:\camera\ftpscript.txt myhost.com", False)
The script starts by suppressing all error messages, as described in the previous example. The subsequent lines use the snapshot utility that comes with nearly all cheap video-conferencing digital cameras to take a photo and save it into a .jpg image file.[6] Note also the line that deletes the old file before the photo is taken, and the line thereafter that checks for the existence of the file before proceeding (in case something went wrong ); this way, we never send the same photo twice. The inclusion of True in the RunProgram line instructs the script to wait for the camera.exe program to complete before the script continues, necessary for a script like this to work. You could alternatively incorporate a Do...Loop loop instead of the simple If statement to repeatedly checking for the file over the course of several seconds.
[6] Refer to the instructions that come with your camera for the specific command-line syntax you should use. Alternately, you could use the Timershot program, one of Microsoft's PowerToys for Windows XP, freely available at http://www.microsoft.com/windowsxp/pro/downloads/powertoys.asp, to automatically photograph your fishtank at regular intervals. You could then use a similar script to upload the file.
The last line then runs the FTP utility that comes with Windows XP to transfer the JPG file to a web server (available for free from nearly all Internet service providers). Normally, FTP is an interactive program, requiring that the user type commands into the console, but the -n and -s options shown here eliminate the need for user interaction. Replace myhost.com with the name of the server containing your web account. Example 9-4 shows the FTP script used by the WSH script in Example 9-3; type it into a plain text file, and save it as ftpscript.txt.
user mylogin pass mypassword bin cd public_html put c:\camera\fish.jpg bye
The FTP script, like a batch file (see Appendix C), is simply a text file containing the commands (in order) that otherwise would be typed manually into the FTP console window. Naturally, you'll want to replace the specifics, like mylogin and mypassword, with your own login and password, respectively, and public_html with the directory containing your public HTML files. Note that all commands must be typed lowercase. Type FTP -? at the command prompt for more command-line parameters, or see Windows XP in a Nutshell (O'Reilly) for more information on FTP.
Next, you'll want to set up a scheduled task to repeatedly run the script; the interval (5 seconds, 5 minutes, etc.) depends on your needs and the capabilities of your system. Lastly, if you haven't already done it, create a web page that references the fish.jpg photo; just visit the page to view a current picture of your fishtank, from anywhere in the world. You can even include JavaScript code in the page to automatically reload itself and update the picture after a certain delay.
This script requires the following subroutines, found earlier in this book: FileDelete, FileExists, and RunProgram.
One of the things that scripting can add to a normal task is to make it conditional; that is, perform certain tasks based on predetermined conditions, eliminating user interaction. A simple example is that of a phone dialer that chooses a different phone number depending on the time of day. That phone number can be the prefix for a long-distance carrier or the number of an Internet service provider. Example 9-5 shows such a script.
On Error Resume Next If Hour(Now( )) >= 8 and Hour(Now( )) <= 17 then Rem During the Day -- Call RunProgram ("c:\links\daytime.lnk", False) Else Rem At Night -- Call RunProgram ("c:\links\nighttime.lnk", False) End If
The script starts by suppressing all error messages, as described in the first script example. The rest of the script is one big If...Then structure, which executes a particular part of the script based on the time of day.
The test is performed with the Hour( ) function, which is built into VBScript.[7] Similar to the Minute( ), Second( ), Day( ), Week( ), Month( ), and Year( ) functions, the expected parameter is a valid time/date string. Here, I've used another built-in function, Now( ), which, not surprisingly, returns the current date and time in the proper format. Hence, Hour(Now( )) returns the current hour in 24-hour time; for 7:00 p.m., it would return 19.
[7] A Visual Basic or VBScript reference will document more cool built-in functions like these.
If it is determined to be daytime (between 8:00 a.m. and 5:00 p.m.), the first code block is used; otherwise, the second code block is used. Naturally, you could put anything you want inside this structure, but for the sake of simplicity, this script just launches one of two shortcuts. The shortcuts could point to dial-up network connections or a phone-dialer utility.
This script requires the RunProgram subroutine, found earlier in this book.
Explorer's SendTo menu contains a list of programs and shortcuts to which any selected file can be sent. The idea is to list programs that could be used with any type of file, such as an email program or file viewer, without having to specifically set up file associations for each supported file type. The following script (Example 9-6) allows you to right-click on any application executable (.exe file), folder, or drive and create a shortcut in the SendTo folder on the spot.
SendToFolder = GetSpecialFolder("SendTo") Call Shortcut("SendToFolder\Notepad.lnk", CommandLine(1))
Whenever we can, we want to make our scripts "smart." If we wanted to be lazy, all we would really need is the second line of this script, which creates a shortcut based on the command-line parameter (see Section 9.8 earlier in this chapter for details). However, the first line uses the GetSpecialFolder function to obtain the location of the SendTo folder from the Registry, which is handy if there's more than one user account (each with its own SendTo folder), if you intend to use this script on more than one computer, or if you don't want to have to modify the script when Microsoft changes the location of the SendTo folder in the next version of Windows.
Once the script has been written, you'll need to associate it with all file types. See Chapter 4 for details on using the "*" file type (located in HKEY_CLASSES_ROOT\*). This script requires the following subroutines, found earlier in this book: CommandLine, GetSpecialFolder, and Shortcut.
Although Explorer lets you rename more than one file at a time (as described in Chapter 2), it's not terribly flexible or intuitive. The command prompt provides a better multiple file-renaming tool (see the Ren command in Appendix C), but it's not always convenient. Example 9-7 shows a script that will rename all the files in a given folder based on rules you choose.
On Error Resume Next FolderName = InputBox("Enter the name of the folder:") If Not FolderExists(FolderName) Then WScript.Quit SearchText = InputBox("Type the text to look for:") ReplaceText = InputBox("Type the text with which to replace" _ & SearchText & ":") If SearchText = "" or ReplaceText = "" Then WScript.Quit Set FileObject = CreateObject("Scripting.FileSystemObject") Set FolderObject = FileObject.GetFolder(FolderName) Set FilesObject = FolderObject.Files FileCount = 0 For Each Filename in FilesObject If InStr(Filename.Name,SearchText) Then Filename.Name = Replace(Filename.Name,SearchText,ReplaceText) FileCount = FileCount + 1 End If Next If FileCount > 0 Then MsgBox FileCount & " files were renamed." Else MsgBox "No filenames containing " & SearchText & " were found." End If
The first section of code is responsible for asking the user for input, including the folder name, the text to look for, and the text with which to replace it. The next three lines set the appropriate objects (for further documentation on these objects, check http://msdn.microsoft.com/scripting/).
The For...Next structure that follows does the real work: this particular example uses a special form of the loop intended to cycle through all the elements of an object array. In this case, the array contains the filenames of all the files in the active folder. The Replace function (built into VBScript) then does the search and replace for each individual filename. Lastly, the FileCount variable keeps track of the number of files renamed, the result of which is tallied in the final code section.
Now, it may take some experience to understand the extensive use of objects in this example, but for the time being, just typing it in will serve as a good example that can be used in other circumstances. This script requires the FolderExists subroutine, found earlier in this book.
Note that a far more powerful file-renaming utility, Power Rename (part of Creative Element Power Tools), is available for Windows XP (download it from http://www.creativelement.com/powertools/).
This script is an automated way to perform the solution described in Section 4.4.2. If you haven't read that section, it's very important that you do so before using this script (see Example 9-8).
|
The solution in Chapter 4 essentially involves creating a folder, creating a shortcut, and creating a text file all possible with a script.
TargetName = CommandLine(1) If TargetName = "" Then TargetName = InputBox("Type the name of the folder to link:") End If If FolderExists(TargetName) = False Then MsgBox "TargetName does not appear to be a valid folder." WScript.Quit End If If Right(TargetName,1) = "\" Then TargetName = Left(TargetName, Len(TargetName) - 1) DesktopFolder = GetSpecialFolder("Desktop") If Right(DesktopFolder,1) <> "\" Then DesktopFolder = DesktopFolder + "\" X = 0 Do Y = X X = InStr(X + 1, TargetName, "\") Loop until X = 0 NewTargetName = DesktopFolder + "Shortcut to " + Mid(TargetName, Y + 1) If FolderExists(NewTargetName) = False Then MsgBox "NewTargetName already exists." WScript.Quit End If FolderCreate(NewTargetName) Call Shortcut(NewTargetName + "\target.lnk", TargetName) Text = "[.ShellClassInfo]" + chr(13) + chr(10) + _ "CLSID2={0AFACED1-E828-11D1-9187-B532F1E9575D}" + chr(13) + chr(10) + _ "Flags=2" + chr(13) + chr(10) + _ "ConfirmFileOp=0" + chr(13) + chr(10) Call WriteToFile(NewTargetName + "\desktop.ini", Text) Call SetAttributes(NewTargetName + "\desktop.ini", 6)
This script is complex, but when broken down, it should be fairly easy to understand. First, the script asks for the name of an existing folder and checks to see if that folder exists. If a trailing slash is found, it is removed. The script then uses the GetSpecialFolder function to read the Registry and obtain the location of the current user's Desktop folder (where the new Folder Shortcut will be placed). The next block of code extracts the name of the folder from the path: if c:\windows\temp is typed, this code extracts the text, temp. The script then forms a new path, checks to see if it already exists, and then creates the new folder.
Then, according to the steps described in Section 4.4.2, a shortcut is created and several lines are written to the file desktop.ini. Lastly, the Hidden and System attributes for desktop.ini are turned on.
The beauty of this script is that it is almost entirely automated. It doesn't ask for any information it's able to safely retrieve itself. The very first line also checks to see if there's a command-line parameter specified. This enables you to use this script in a folder's context menu, so that you could right-click on any folder and select Make Folder Shortcut, and the script would do the rest. See "Using Command-Line Parameters in Scripts" earlier in this chapter and Section 4.3.1 for details. For another, similar example, see Section 4.3.5.
This script requires the following subroutines, which are found earlier in this book: CommandLine, FolderCreate, FolderExists, GetSpecialFolder, RegistryRead, SetAttributes, and WriteToFile.
The previous example script does not accommodate Folder Shortcuts for FTP sites, although it can be modified to work with Internet Shortcut files instead of Folders.
Regardless, I leave it to you to put the final pieces together!