File Operations

Overview

The default Windows Script Host (WSH) scripting languages (VBScript and JScript) do not have any built-in file manipulation capabilities, nor does WSH itself. This functionality is provided by the COM File System Object (FSO) that is part of the Microsoft Scripting Runtime Library.

The FSO exposes a number of separate objects that provide the ability to perform file-related operations. Table 5-1 lists the objects exposed by the FSO component.

Table 5-1: FileSystemObject Objects

OBJECT

DESCRIPTION

Folders

A collection that contains a list of folders in a specified folder

Folder

Exposes folder information such as size, attributes, and date information, and methods to move, delete, and copy

Files

A collection that contains a list of files in a specified folder

File

Exposes file information such as size, attributes, and date information, and methods to move, delete, and copy

Drives

Collection object that contains a list of available drives on the local machine

Drive

Exposes drive information, such as size and type

TextStream

Supports text file creation and manipulation

The FSO exposes methods and properties that perform file manipulation operations. Before you can use any of the objects listed in Table 5-1 you must create an instance of the FSO:

'create an instance of an FSO object Set objFSO = CreateObject("Scripting.FileSystemObject")

See Also

The Scripting Run-Time Reference and File System Object Tutorial, which is part of the VBScript or JScript documentation, is available for download at http://msdn.microsoft.com/scripting.

Determining the Readiness of a Floppy Drive

Problem

You want to check if a floppy drive is usable.

Solution

Use the IsReady property to determine if a given drive is available for operations:

Dim objFSO, objDrive Set objFSO = CreateObject("Scripting.FileSystemObject") Set objDrive = objFSO.GetDrive("A") 'check if drive is ready, If objDrive.IsReady Then 'drive is ready, do something.. End If

Discussion

The Drive object provides information on system drives. These may be fixed, CD-ROM, removable, or network drives. To get a reference to a Drive object, use the FSO object's GetDrive method. Its syntax is as follows:

Set objDrive = objFSO.GetDrive(strDriveSpec)

The strDriveSpec parameter identifies which drive to reference. You can represent the parameter as a single drive letter or a network UNC path; it is not case-sensitive. If you pass a drive letter, you can specify the drive letter followed by a colon or a colon and backslash.

If you specify a drive using a UNC path, you don't need to connect the network share as a drive. The following code snippet demonstrates different methods of identifying a drive:

Dim objFSO, objDrive Set objFSO = CreateObject("Scripting.FileSystemObject") 'the following will return a drive object for the D: drive Set objDrive = objFSO.GetDrive("D") Set objDrive = objFSO.GetDrive("d:") 'return the drive object for a network share Set objDrive = objFSO.GetDrive("\thord$")

Table 5-2 contains Drive object properties. All properties are read-only unless otherwise specified.

Table 5-2: Drive Object Properties

PROPERTY

DESCRIPTION

AvailableSpace, FreeSpace

Free space on the drive in bytes. These properties return the same information.

DriveLetter

Drive letter associated with the drive.

DriveType

Type of drive. Unknown=0, Removable=1, Fixed=2, Remote=3, CD-ROM=4, and RamDisk=5.

FileSystem

File system that the drive uses (e.g., FAT, NTFS, or CDFS).

IsReady

Returns True if the drive is ready for access; otherwise it returns False. A removable media drive (such as a CD-ROM drive) will be "not ready" if there is no disc in the drive. A network drive will be "not ready" if it is disconnected.

Path

Returns the drive path.

RootFolder

Returns the root folder for the drive as a Folder object.

SerialNumber

Serial number uniquely identifying the drive.

ShareName

Displays the share name in the case of a network drive. Returns a blank string for a local drive.

TotalSize

Total size of the drive in bytes.

VolumeName

Name of the drive. This is read/write, so you can set a drive's volume name.

Listing the Drives on a System

Problem

You want to list information on system drives.

Solution

You can use the FSO's Drives collection to enumerate system drives:

Dim objFSO, objDrive Set objFSO = CreateObject("Scripting.FileSystemObject") For Each objDrive In objFSO.Drives 'check if drive is ready, If objDrive.IsReady Then Wscript.Echo objDrive.DriveLetter & " is " & _ Fix(((objDrive.TotalSize - objDrive.FreeSpace) _ / objDrive.TotalSize) * 100) & "% used" Else Wscript.Echo objDrive.DriveLetter & " is not ready" End If Next

Discussion

The Drives collection contains a list of drives available to the local machine. This includes any drive visible to the system, including fixed hard, removable floppy, CD-ROM, or network drives. This collection is returned from the FileScriptingObject. The information for each object in the collection is exposed as a Drive object.

You can reference drives from the collection by specifying a drive letter. The drive letter is not case-sensitive and may be followed by a colon or a colon and backslash, as demonstrated by the following code snippet:

Set objFSO = CreateObject("Scripting.FileSystemObject") 'the following two statements return a reference to the C drive Set objDrive = objFSO.Drives("C:") 'get a reference to the C drive Set objDrive = objFSO.Drives("C") 'get a reference to the C drive

If you reference a drive in the collection that does not exist, an error occurs. If you need to check for the existence of a drive, use the FSO DriveExists method. The syntax is as follows:

bResult = objFSO.DriveExists(strDrive)

The strDrive parameter identifies which drive to check. It is not case-sensitive and may be followed by a colon or a colon and backslash. If the drive exists, it returns True; otherwise, it returns False. The following example checks if the drive F: exists:

Set objFSO = CreateObject("Scripting.FileSystemObject") If objFSO.DriveExists("F:") Then Wscript.Echo "Drive f: exists" End If

Finding the Size of a User Directory

Problem

You want to list the size of user directories.

Solution

You can use the GetFolder method to retrieve a reference to the user root Folder object, and then iterate through each subfolder of the object's SubFolders collection:

Dim objFSO, objFolder, objSub, nTotal Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFolder = objFSO.GetFolder("D:Users") nTotal = 0 'loop through each subfolder, displaying its size For each objSub In objFolder.SubFolders Wscript.Echo "Folder " & objSub.Name & " is " & objSub.Size _ & " bytes" nTotal = nTotal + objSub.Size Next Wscript.Echo "Total for all folders:" & nTotal & " bytes"

Discussion

Folders (also referred to as directories) are used by Windows to organize files and folders. To obtain a reference to a Folder object, use the FSO's GetFolder method. The syntax is as follows:

Set objFolder = objFSO.GetFolder(strFolderPath)

The strFolderPath parameter identifies the folder to return. This can be the path to either a local folder or a network UNC, and it is not case-sensitive:

Dim objFSO, objFolder, objFolder2 Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFolder2 = objFSO.GetFolder("e:data") Set objFolder = objFSO.GetFolder("\thore$data")

Table 5-3 lists Folder object's properties. Properties are read-only unless otherwise indicated.

Table 5-3: Folder Properties

PROPERTY

DESCRIPTION

Attributes

Folder attributes

DateCreated, DateLastAccessed, or DateLastModified

Returns the folder created, last accessed, and last modified dates

Drive

The Drive object where the folder resides

Files

Collection containing all files in the folder

IsRootFolder

Boolean value; returns True if Folder is a root folder

Name

Name of folder

ParentFolder

Folder object for parent folder

Path

Full path to the file

Size

Size of the folder

ShortName/ShortPath

MS-DOS short name (8.3 format) for the folder

SubFolders

Folders collection containing all Folder objects in a folder

Type

Type description, returns File Folder

Determining the Size of a File

Problem

You need to determine the size of a file.

Solution

You can use the File object's Size property to return the file size:

Dim objFSO, objFile, nSize 'create an instance of an FSO object Set objFSO = CreateObject("Scripting.FileSystemObject") 'get a reference to a specified file Set objFile = objFSO.GetFile("d:data eport.doc") nSize = objFile.Size 'get the size of the file

Discussion

You obtain the File object for an individual file by using the FSO's GetFile method. The syntax is as follows:

Set objFile = objFSO.GetFile(strFilePath)

The strFilePath is the path to the file. This can either be the path to a local file or a network UNC, and it is not case-sensitive.

Once you have obtained a File object, you can inspect a number of file-related properties in addition to the file's size. Table 5-4 lists the File object's properties. All properties are read-only unless otherwise specified.

Table 5-4: File Object Properties

PROPERTIES

DESCRIPTION

Attributes

Read/Write. File attributes. Numeric value comprised of one or more file attribute types. The attribute values are added together to form the read-write Attributes property. The individual attribute values are Normal=0, Hidden=2, System=4, Volume=8, Archive=32, and Compressed=2048.

DateCreated, DateLastAccessed, or DateLastModified

Returns the file's created, last accessed, and last modified dates.

Drive

The Drive object on which a file resides.

Name

Read/Write. Name of file.

ParentFolder

Folder object that contains the file's parent folder.

Path

Full path to the file.

ShortName/ShortPath

MS-DOS short name (i.e., in 8.3 format) for the file.

Size

Size of the file in bytes.

Type

File type description (e.g., Text Document).

Reading and Changing File Attributes

Problem

You want to change a file's read-only and/or hidden attributes.

Solution

You can use the File object's Attributes property to read and set a file's attributes:

'set read-only and toggle hidden attribute for a file Const ReadOnly = 1 Const Hidden = 2 Dim objFSO, objFile Set objFSO = CreateObject("Scripting.FileSystemObject") 'get a reference to a file Set objFile = objFSO.GetFile("e:data eport.doc") 'set the Readonly attribute objFile.Attributes = objFile.Attributes Or ReadOnly 'toggle the Hidden attribute objFile.Attributes = objFile.Attributes Xor Hidden

Discussion

A file attribute is a combination of any of the values listed in Table 5-5.

Table 5-5: File Attribute Values

CONSTANT

VALUE

DESCRIPTION

Normal

0

No attributes are set.

ReadOnly

1

Read-only access.

Hidden

2

Hidden file.

System

4

System attribute.

Archive

32

Used by backup programs to determine if the file has been changed since the last operation. File is always turned on when any modification is made to a file.

Compressed

2048

Compressed files.

To check if an attribute is set, use the And operator to perform a bitwise comparison of a file attribute with the value of the attribute you are checking for. The following example checks if the archive attribute is set:

Const Archive= 32 Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.GetFile("e:data eport.doc") If objFile.Attributes And Archive Then Wscript.Echo "Archive bit is set" End If

If you And the binary value against another value and the bit you are checking for is set, the bitwise operation returns the value you are checking for. In the previous example, And-ing the file attribute against 32 (the value for the archive attribute) returns 32 if the archive bit is set.

To set an attribute, use the bitwise Or operator to set the bit. The following example sets the archive bit:

objFile.Attributes = objFile.Attributes Or Archive

To turn off an attribute, perform the Not And bitwise operation against the value you want to change together with the attribute value you want to reset. The following example turns off the archive bit:

objFile.Attributes = objFile.Attributes Not And Archive

To "toggle" an attribute (in other words, to turn the attribute "off" if it is "on" or "on" if it is "off"), perform the Xor bitwise operation with the value you want to change against the bit value you want to change. The following example toggles the archive bit for a file:

objFile.Attributes = objFile.Attributes Xor Archive

You can turn the archive, readonly, system, and hidden attributes for all files except certain system files. You can read but not modify the compressed attribute. See Chapter 10 for methods of compressing and uncompressing files and folders using WMI.

The archive attribute can be useful for scripts where you only want to process files that have not been manipulated since the last execution of the script. Whenever a file is created or modified, the file system turns the archive bit on.

In the following example, all the files in a document folder are copied to a network backup folder if the archive attribute is not set.

Const Archive= 32 Dim objFSO, objFile, objFolder Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFolder = objFSO.GetFolder("d:datadocuments") For Each objFile In objFolder.files 'check if the archive attribute is set If objFile.Attributes And Archive Then 'copy to backup location objFile.Copy "h:ackupdocuments" 'turn the archive bit off objFile.Attributes = objFile.Attributes And Not Archive End If Next

Turning the archive bit off does not have any adverse effects on a file. Note that some backup software and certain MS-DOS commands such as XCOPY may use this attribute to determine if a file has been created or modified since the last operation.

See Also

Solution 10.11.

Determining the Existence of a File or Folder

Problem

You need to check if a file exists.

Solution

You can call the FSO's FileExist method:

Dim objFSO 'create an instance of an FSO object Set objFSO = CreateObject("Scripting.FileSystemObject") 'check if the specified file exists If objFSO.FileExists("d:data eport.doc") Then WScript.Echo "File exists" End If

Discussion

The FSO object's FileExists method returns True if the specified file exists and False otherwise. Its syntax is as follows:

bExists = objFSO.FileExists(strPath)

The strPath parameter represents the path and name of the file, and it can be either a local file path or UNC format (e.g., \thordata eport.doc).

To determine if a folder exists, use the FSO object's FolderExists method. Its syntax is as follows:

bFlag = objFSO.FolderExists(strPath)

The strPath parameter identifies the folder path you want to check. It can be a local path or a network path that is specified by using the UNC. The path may be followed by a backslash. The function returns True if the path exists and False if the path is not found. The following code snippet tests for the existence of the folder H:data:

Set objFSO = CreateObject("Scripting.FileSystemObject") bFlag = objFSO.FolderExists("H:Data")

Renaming a File or Folder

Problem

You want to rename a file or folder.

Solution

You can modify the file or folder object's Name property:

Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.GetFile("d:data eport.doc") objFile.Name = "newreport.doc"

Discussion

To rename a file or folder, change the Name property to the new name of the file or folder.

If you are renaming a file that is currently opened by another application, the operation may fail and an error will occur. If you attempt to rename a folder that has open files in it, the operation fails and an error occurs.

Comparing Files by Version Number

Problem

You want to compare files from two different folders and list any files that have different version numbers.

Solution

The following script uses the FSO's GetFileVersion method to compare the version of each file that is found in two specified folders that have different version numbers:

'compvers.vbs Dim objFSO, strFolder1, strFolder2, objFolder Dim objFile, strVer1 'check if correct number of arguments passed If WScript.Arguments.Count <> 2 Then WScript.Echo _ WScript.ScriptName & _ " compares versions of files in two folders." & vbCrLf & _ "Output is all files which exist in both folders but " & vbCrLf & _ "have different version stamps." & vbCrLf & _ "Syntax:" & vbCrLf & _ WScript.ScriptName & " folder1 folder2" & vbCrLf & vbCrLf WScript.Quit -1 End If strFolder1 = WScript.Arguments(0) strFolder2 = WScript.Arguments(1) Set objFSO = CreateObject("Scripting.FileSystemObject") EnsureFolder strFolder1 EnsureFolder strFolder2 Set objFolder = objFSO.GetFolder(strFolder1) 'loop through each file in folder and compare with second folder For Each objFile In objFolder.Files strPath2 = strFolder2 & objFile.Name If objFSO.FileExists(strPath2) Then CompareFiles objFile, objFSO.GetFile(strPath2) End If Next 'check if folder exists Sub EnsureFolder(strFolder) If Not objFSO.FolderExists(strFolder) Then WScript.Echo strFolder & " is not a valid folder." & vbCrLf WScript.Quit -1 End If 'append backslash to folder if does not exist If Right(strFolder, 1) <> "" Then strFolder = strFolder & "" End Sub 'compare versions of two passed file objects and display version info 'if different Sub CompareFiles(objFile1, objFile2) If objFSO.GetFileVersion(objFile1.Path) = _ objFSO.GetFileVersion(objFile2.Path) Then Exit Sub WScript.Echo objFile1.Path & " has version [" & _ strVer1 & "] and " & _ objFile2.Path & " has version [" & _ strVer2 & "]" End Sub

Discussion

The FSO object's GetFileVersion method returns the version of a specified file. It was introduced in WSH version 2.0. Its syntax is as follows:

strVersion = objFSO.GetFileVersion(strPath)

The strPath parameter represents the path to the file, and it can be either a local or UNC file path.

GetFileVersion returns a file version as a string for any file that has a file version associated with it. It is mainly for application-related files, such as DLL and EXE files. If the file has no version, it returns an empty string.

Creating a Folder

Problem

You want to create a folder.

Solution

You can use the FSO's CreateFolder method or a Folders object's Add method to create a new folder. The following script demonstrates both methods:

Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFolder1 = objFSO.CreateFolder("c:data") 'create a folder below the new data folder using the Folders object's Add method Set objFolder2 = objFolder1.SubFolders.Add("Word")

Discussion

You can create file folders by using the FSO object's CreateFolder method. Its syntax is as follows:

Set objFolder = objFSO.CreateFolder (strPath)

The strPath parameter identifies the folder path that you want to create. It can be a local path or a network path that you specify by using a UNC. The path can be followed by a backslash. If the path does not exist, an error occurs. If successful, the method returns a Folder object for the newly created folder.

Alternatively, you can use the Folder object's Add method:

Set objFolder = objFolder.Add(strPath)

This method creates a folder that is relative to its parent folder, which means you can only create a folder. The path specified by the strPath parameter is relative to the Folder object's parent folder.

Set objFolder1 = objFSO.CreateFolder("c:data") 'create a folder below the new data folder using the Folders object's Add method Set objFolder2 = objFolder1.SubFolders.Add("Word")

If successful, the method returns a Folder object for the newly created folder. These methods can only create one folder at a time. If you want to create a folder structure in which one or more folders in the path do not exist, you must first create the parent folder:

'create the folder H:DataWordReports Set objFSO = CreateObject("Scripting.FileSystemObject")Set objFolder = objFSO.CreateFolder("H:Data") Set objFolder = objFSO.CreateFolder("H:DataWord") Set objFolder = objFSO.CreateFolder("H:DataWordReports")

The following subroutine, CreatePath, provides a more flexible method of creating a folder:

Sub CreatePath(strPath) Dim nSlashpos, objFSO Set objFSO = CreateObject("Scripting.FileSystemObject") ' strip any trailing backslash If Right(strPath, 1) = "" Then strPath = Left(strPath, Len(strPath) - 1) End If 'if path already exists, exit If objFSO.FolderExists(strPath) Then Exit Sub 'get position of last backslash in path nSlashpos = InStrRev(strPath, "") If nSlashpos <> 0 Then If Not objFSO.FolderExists(Left(strPath, nSlashpos)) Then CreatePath Left(strPath, nSlashpos - 1) End If End If objFSO.CreateFolder strPath End Sub

This routine creates a specified folder hierarchy. If any folders in the path do not exist, they are created. The syntax is as follows:

CreatePath strFolderPath

The strFolderPath parameter identifies the path you want to create. The CreatePath routine uses the FSO object's FolderExists method to check if a folder exists.

Finding and Deleting Temporary Files

Problem

You want to list files from a directory structure that meet certain criteria.

Solution

The following code contains the logic for the Windows Script component ENTWSH.RecurseDir, which recursively searches a specified directory and subdirectories for files that meet certain criteria:

The ENTWSH.RecurseDir scripting component is used to recurse a directory structure and then process all files that meet a certain condition. When a file meets the condition, an event is fired, which allows you to perform a user-defined operation against the file.

The following script example creates an instance of the ENTWSH.RecurseDir component. It searches for all files under a specified path (d:data) with the extension .tmp and deletes them:

'deltemp.vbs Dim objDelTempFiles , objFSO 'create an instance of the ENTWSH.RecurseDir object. 'any sinked events will be prefixed with ev_ Set objDelTempFiles = Wscript.CreateObject ("ENTWSH.RecurseDir","ev_") Set objFSO = CreateObject("Scripting.FileSystemObject") objDelTempFiles.Path = "d:data" 'set the path to search 'set the filter for files to find. This will find all files with tmp extension objDelTempFiles.Filter = ".tmp$" objDelTempFilesEvent.Process Sub ev_FoundFile(strPath) objFSO.DeleteFile strPath End Sub

Discussion

The ENTWSH.RecurseDir object searches the path, including all subfolders, for files that meet the specified filter pattern. When a file is found that matches the pattern, the FoundFile event is fired.

To use the object, register the ENTWSH.RecurseDir script.

The calling script is responsible for providing an event handler. The path of the file that is found is passed to the event handler as a parameter; the resulting event can perform any required processing. Table 5-6 lists the properties of the RecurseDir object.

Table 5-6: ENTWSH.RecurseDir Object Properties

ATTRIBUTES

DESCRIPTION

Path

Path you want to search (e.g., d:data).

Filter

Optional. Specifies filter for files you want to process. This filter is a regular expression pattern. If this property is not set, all files will be processed. Examples:

.tmp$

Return all tmp files, same as *.tmp.

.tmp$|.bat$

Return all tmp files and bat files.

Once the properties have been set in the calling script, you can call the RecurseDir component's Process method. The Process method recursively goes through all folders under the specified path.

When a file is found that matches the pattern specified by the Filter property, the FoundFile event is fired. The event parameters are the path and name of this file. The event handler can then determine what action to take with the file.

Finding Files That Meet Criteria

Problem

You want to list files from a folder structure that meet certain criteria.

Solution

You can use the Edir.vbs solution script:

'edir.vbs 'enhanced directory utility. Lists all files that meet criteria from 'specified directories Dim strCriteria, objFile, objFSO, objArgs Set objArgs = Wscript.Arguments 'check if less than 2 arguments are being passed If objArgs.Count < 2 Then ShowUsage Wscript.Quit -1 End If Set objFSO = CreateObject("Scripting.FileSystemObject") If Not objFSO.FolderExists(objArgs(0)) Then Wscript.Echo "Path '" & objArgs(0) & "' not found " Wscript.Quit -1 End If Set objEvent = Wscript.CreateObject ("ENTWSH.RecurseDir","ev_") objEvent.Path = objArgs(0) strCriteria = objArgs(1) strCriteria = Replace(strCriteria, "Size","objFile.Size",1,-1,1) strCriteria = Replace(strCriteria, "Modified", _ "objFile.DateLastModified",1,-1,1) strCriteria = Replace(strCriteria, "Accessed", _ "objFile.DateLastAccessed",1,-1,1) strCriteria = Replace(strCriteria, "Created", _ "objFile.DateCreated",1,-1,1) strCriteria = Replace(strCriteria, "Attributes", _ "objFile.Attributes",1,-1,1) 'check if third argument passed - this is regular expression file filter If objArgs.Count = 3 Then objEvent.Filter = objArgs(2) End If Set objFSO = CreateObject("Scripting.FileSystemObject") objEvent.Process Sub ShowUsage WScript.Echo "edir. Enhanced directory." & vbCrLf & _ "Syntax:" & vbCrLf & _ "edir.vbs path criteria [filter] [/s]" & vbCrLf & _ "path path to folder to search " & vbCrLf & _ "criteria criteria to filter files on " & vbCrLf & _ "filter option regular expression filter " End Sub Sub ev_FoundFile(strPath) Set objFile = objFSO.GetFile(strPath) If Eval(strCriteria) Then Wscript.StdOut.WriteLine strPath End If End Sub

Discussion

There are no built-in commands in the command-line environment to list files that meet certain criteria, apart from using the DIR wildcards to return filenames that match a certain pattern.

The Edir.vbs solution script provides the functionality to execute relatively complex search expressions. It recursively searches a specified folder path for all files that meet the criteria. The script uses the ENTWSH.RecurseDir Windows Script component to perform the directory recursion.

The following command-line statement lists all files under the d:users directory that are greater than 500,000 bytes in size and have been modified before January 1, 1999:

edir "Size > 500000 And modified<#1/1/99# " "d:users"

The expression that is executed can contain any number of conditional logic operators (such as And, Or, Not, and so on). Table 5-7 lists the filename properties that you can filter.

Table 5-7: Filename Properties

FILE

DESCRIPTION

Size

Size of file

Modified

Last modified date and time

Created

Creation date and time

Attributes

File attributes

Accessed

Last accessed date and time

The script can take an optional parameter to filter filenames. This parameter is passed as a regular expression. This regular expression is evaluated against each file as well as the file properties criteria. The following command-line statement lists all files with a .doc extension that are over 500,000 bytes:

edir "Size > 500000" "d:users" ".doc$"

The script uses the VBScript Eval function to evaluate the expressions. The Eval function is a recent addition to VBScript. The syntax is as follows:

result = Eval(strExpression)

The strExpression parameter is any valid expression. If successful, Eval returns the evaluated expression.

The following example creates a simple command-line calculator:

'calc.vbs Dim objArgs Set objArgs = Wscript.Arguments If objArgs.Count=1 Then Wscript.StdOut.WriteLine Eval(objArgs(0)) Else Wscript.StdErr.WriteLine "calc.vbs. Performs mathematical operations" & _ vbCrLf & "Syntax: " & vbCrLf & _ "calc.vbs expression " & vbCrLf & _ "expression mathematical expression" End If

To use calc.vbs, you can pass an expression to the command-line script, which is demonstrated in the following example:

calc "5*10+10/5-(5+6*3)"

Eval can access all global script variables from the current executing script. The search keywords (size, modified, and so on) are replaced with a string representing the file in the script.

Deleting a Folder

Problem

You want to delete a folder.

Solution

You can use the FSO's DeleteFolder or the Folder object's Delete method to delete a folder:

Dim objFSO, objFolder Set objFSO = CreateObject("Scripting.FileSystemObject") 'delete the folder e:dataword objFSO .DeleteFolder "e:dataword" 'get and delete the folder e:dataexcel Set objFolder = objFSO.GetFolder("e:dataExcel") objFolder.Delete

Discussion

You can delete folders by invoking the FSO object's DeleteFolder method. Its syntax is as follows:

objFSO.DeleteFolder strPath [,bForce]

The strPath parameter is the path to the folder to delete. The path can be in UNC format and it can contain wildcards. The DeleteFolder method deletes the folder and any content below the folder.

The optional bForce parameter is a Boolean value that, when True, indicates if any item in the folder being deleted is flagged as read-only locked. If this is the case, it attempts to force the deletion if required. The default is False.

If the bForce parameter is False (the default) and the DeleteFolder method encounters a read-only folder or file while executing, an error occurs and the method terminates. The directory being deleted is left in an incomplete state because some folders and files in the structure may have been deleted before the operation terminated.

You can also remove folders by invoking the Delete method for a Folder object. Its syntax is as follows:

objFolder.DeleteFolder [bForce]

The bForce parameter is the same as the bForce parameter for the DeleteFolder method.

No files or folders removed using DeleteFolder or Folder object's Delete method are put in the Recycle Bin. You should be careful when using these methods because they could cause a great deal of irreversible damage if the wrong folder, such as the root of your C: drive, is removed.

Copying a File

Problem

You need to copy a file.

Solution

You can use the File object's Copy method to copy a file:

Dim objFSO, objFile Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.GetFile("C:Data eport.doc") 'copy items from folder to network folder objFile.Copy "H:Data"

Discussion

The File object's Copy and Move methods copy or move the specified file to a specified destination. Their respective syntaxes are as follows:

objFile.Copy strDestination [,bOverwriteFiles] objFile.Move strDestination

Both methods require a destination parameter. The destination may be a folder or a new filename.

When you specify a folder, make sure the path ends with a backslash (). If you do not do so, the method assumes that you are trying to copy or move the file to a new file with the name of the folder, and the operation generates an error. The Copy and Move methods do not attempt to create folders if they do not exist.

The Copy method has an optional parameter. This parameter is set to True by default, but if it is set to False, the copy operation generates an error if a file already exists in the destination folder. If the destination file has the same name as the source and the destination is flagged as read-only and/or hidden, a copy fails, even if the bOverWriteFiles flag is set.

You can also use two other methods for copying and moving files-namely, the FSO's CopyFile and MoveFile methods. The File object's Copy and Move methods only perform the operations on the individual File objects. The CopyFile and MoveFile methods allow you to copy individual files as well as process multiple files using wildcards. Their respective syntaxes are as follows:

objFSO.CopyFile strSource, strDestination [,bOverwriteFiles] objFSO.MoveFile strSource, strDestination

The strSource parameter identifies one or more files that you want to process. You can use the wildcards * and ? to filter the files you want to process.

The strSource and strDestination parameters are the same as the parameters of the File object's Copy and Move methods. They identify the destination folder or file to copy or move the source file(s) to. If the destination directory does not exist, an error occurs. You cannot use wildcards in the destination path.

The CopyFile method's optional bOverwriteFiles parameter overwrites a file(s) in the destination directory that has the same name as a file(s) from the source directory. By default the parameter is set to True. If it is set to False, an error occurs if there is an attempt to copy a file from the source directory that has the same name as a file in the destination directory. If this happens, the CopyFile operation does not attempt to "roll back" any file copy operations that have already been completed successfully.

Set objFSO = CreateObject("Scripting.FileSystemObject") 'copy all VBS files from wsh to backup directory objFSO.CopyFile "d:datawsh*.vbs", "d:dataackup" 'try copying again to the backup folder, an error will occur 'since the overwrite flag is set to False objFSO.CopyFile "d:*.vbs", "d:dataackup", False 'an error would occur here since cannot use wildcards in destination name objFSO.MoveFile "d:*.vbs", "d:dataackup*.vbs"

Copying and Moving a Folder

Problem

You want to copy data from a local folder to a network folder.

Solution

You can use the Folder object's Copy method:

Dim objFSO, objFolder Set objFSO = Wscript.CreateObject("Scripting.FileSystemObject") Set objFolder = objFSO.GetFolder("C:Data") 'copy items from folder to network folder objFolder.Copy "H:Data"

Discussion

The Copy and Move methods copy or move the contents of a specified folder to a specified destination folder. Their respective syntaxes are as follows:

objFolder.Copy strDestination, [,bOverwriteFiles] objFolder.Move strDestination

Both methods require a strDestination destination folder parameter. The Copy method has an optional bOverWriteFiles parameter. These parameters are the same as those used in the File object's corresponding Copy and Move methods. This parameter is set to True by default. If it is set to False, the copy operation generates an error if a file already exists in the destination folder.

The contents of all files and folders in the strDestination folder are either be copied or moved to the specified destination.

Two other methods for copying and moving folders are the FSO's CopyFolder and MoveFolder methods. Their syntaxes are as follows:

objFSO.CopyFolder strSource, strDestination [,bOverWriteFiles] objFSO.MoveFolder strSource, strDestination

The strSource and strDestination parameters are the same as those of the Folder object's Copy and Move methods. The CopyFolder and MoveFolder methods do not require that you first get a reference to a Folder object.

If you use bOverwriteFiles with Copy/CopyFolder or use the Move/MoveFolder methods, an error occurs if any file or folder exists in the destination path, including the root folder of the destination path itself.

You should take care when moving whole directories because the source directory may contain files that other applications are dependent on and these applications may not function correctly if any dependent files are moved to another location.

Deleting a File

Problem

You want to delete a file.

Solution

You can call the FSO's DeleteFile or the File object's Delete method:

Dim objFSO, objFile Set objFSO = CreateObject("Scripting.FileSystemObject") objFSO.DeleteFile "d:data eport.doc" Set objFile = objFSO.GetFile("d:datapayroll.xls") objFile.Delete

Discussion

The FSO object's DeleteFile method deletes a specified file. Its syntax is as follows:

objFSO.DeleteFile strPath [,bForce]

The strPath parameter is the path to the file(s) to delete. The directory path can be a standard file path or it can use UNC format. You can use the wildcards * and ? to specify multiple files to delete. You must provide file criteria, either by specifying a single file or by using a wildcard.

Providing the path to a directory (as you can do using the DELETE command) does not delete the contents of the directory-you must use wildcards (*.*) after the directory path to delete the contents. If you specify a wildcard for a specific file (e.g., *.DOC) and no files that meet the criteria are found, an error occurs. This doesn't happen if you use the *.* wildcards and no files are found.

Set objFSO = CreateObject("Scripting.FileSystemObject") 'attempt to delete the contents of the data directory 'this won't do anything - no error will occur objFSO.DeleteFile "d:data" 'this will delete the contents of the data directory objFSO.DeleteFile "d:data*.*"

The optional bForce parameter is a Boolean value and, if set to True, it attempts to force the deletion of read-only files. The default is False. If the file that is specified for deletion does not exist, an error occurs. If you attempt to delete multiple files, the DeleteFile operation terminates when the error is encountered.

The File object's Delete method deletes a specified file. Its syntax is as follows:

objFile.Delete [,bForce]

The File object's Delete method can also take an optional bForce parameter (like the DeleteFile method) that attempts to force the deletion of a read-only file. The default is False.

Files deleted using either the DeleteFile or Delete method are not moved to the Recycle Bin.

Creating and Writing to a Text File

Problem

You want to create a text file and add some text to it.

Solution

You can use the FSO's CreateTextFile method to create a new TextStream object, and then add text using either the Write or WriteLine methods:

Dim objFSO, objTextFile Set objFSO = CreateObject("Scripting.FileSystemObject") Set objTextFile = objFSO.CreateTextFile("D:data.txt") objTextFile.WriteLine "Write a line to a file with end of line character" objTextFile.Write "Write string without new line character" objTextFile.Close

Discussion

The TextStream object provides powerful text file creation and manipulation abilities. To create a new TextStream object, invoke the FSO object's CreateTextFile method. Its syntax is as follows:

Set objText = objFSO.CreateTextFile(strFileName, [bOverwrite],[ intTriState])

The strFileName parameter identifies the new filename. The optional bOverwite parameter overwrites an existing file with the same name if True. The default value is True. If the bOverwite parameter is set to False and the file that is specified by strFileName exists, an error occurs. The optional intTriState parameter creates a Unicode file if set to -1; it creates an ASCII file if set to 0. A value of -2 uses system settings. The default is 0.The following example creates a new text file:

Set objFSO = CreateObject("Scripting.FileSystemObject") Set objTextFile = objFSO.CreateTextFile("C:Datadata.txt")

Once you have created a TextStream object, you are ready to write data to it. The Write or WriteLine methods write data to the file. Their syntax is as follows:

objTextStream.Write|WriteLine strText

The strText parameter is the text that is written to the file. The difference between the Write and WriteLine methods is that the WriteLine method writes an end-of-line character (represented by the VBScript intrinsic constant vbCrLf) at the end of the line.

You can add blank lines to a text file using the WriteBlankLines method:

objTextStream.WriteBlankLines nLinesCount

A blank line represents a carriage return/linefeed combination.

Whenever you are done performing operations on a TextStream object, call its Close method. The Close method closes the object and writes any updates to the file to disk.

Opening and Reading a File

Problem

You want to read a text file.

Solution

You can use the FSO's OpenTextFile method to open a file, and you can use the Read or ReadLine methods to read individual lines. The following sample contains a function that searches a specified .ini file for a key and then returns the associated value:

'readini.vbs Dim dAccess dAccess = ReadINI("e:data.ini", "DateLastAccessed") Function ReadINI(strINIFile, strKey) Dim objFSO, objTextFile, strLine Set objFSO = CreateObject("Scripting.FileSystemObject") Set objTextFile = objFSO.OpenTextFile(strINIFile) 'loop through each line of file and check for key value Do While Not objTextFile.AtEndOfStream strLine = objTextFile.ReadLine If Left(strLine, Len(strKey) + 1) = strKey & "=" Then ReadINI = Mid(strLine, InStr(strLine, "=") + 1) End If Loop objTextFile.Close End Function

Discussion

To open an existing text file, call the FSO's OpenTextFile method. Its syntax is as follows:

Set objText = objFSO.OpenTextFile(strFileName, [intIOMode],[ bCreat],[ intTriState])

Table 5-8 lists the OpenTextFile method parameters.

Table 5-8: OpenTextFile Method Parameters

PARAMETER

DESCRIPTION

strFileName

Name of file to open.

intIOMode

Optional. Specifies whether file is to be opened for Reading =1, Writing=2, or Appending=8. The default is Reading.

bCreate

Optional. If set to True, a new text file will be created if it is not found. The default is False.

TriState

Optional. If -2, it opens the file using file system settings; -1 uses Unicode; and 0 uses ASCII. The default is 0.

An alternative is to invoke the OpenAsTextStream method on an existing File object:

Set objText = objFile.OpenAsTextStream([intIOMode],[ intTriState])

The intIOMode and intTriState parameters correspond to the parameters in the OpenTextFile method. Also like the OpenTextFile method, OpenAsTextStream returns a TextStream object.

If you have opened the file for read access, you can read parts of the file or the whole file. There are three methods for reading data. The ReadAll method returns the whole text file as a string. ReadLine reads the line up to the end-of-line character sequence. The Read method reads a specified number of characters.

strData = objTextFile.ReadLine 'read a single line strData = objTextFile.Read(10) 'read 10 characters strData = objTextFile.ReadAll 'read the whole file

If you are reading the file either character by character using the Read method or line by line using the ReadLine method, you need to be able to determine when you hit the end of the file. You do this by retrieving the value of the AtEndOfStream property. AtEndOfStream is True if the file pointer is at the end of the file; otherwise, it is False.

You should also check the AtEndOfStream property when using the ReadAll method-attempting to read an empty file using ReadAll generates an error.

If you want to jump a number of characters or lines when processing a text file, you can use the SkipLine or Skip method. Their syntaxes are as follows:

objTextFile.Skip nChars objTextFile.SkipLine

SkipLine moves to the next line, which is the position after the next carriage return/linefeed combination. The Skip method skips nChars characters. The Skip method can only move forward in a file; you cannot move backward by specifying a negative value.

Updating a Text File

Problem

You want to update a text file.

Solution

The following script contains a routine to update a key in an .ini file:

'iniwrite.vbs 'updates an INI file entry Const ForWriting = 2 Const ForAppending = 8 UpdateINI "e:settings.ini", "DateLastAccessed", Now Sub UpdateINI(strINIFile, strKey, strValue) Dim objFSO, objTextFile, strFileText, aDataFile, nF, bFound Set objNetwork = CreateObject("WScript.Network") Set objFSO = CreateObject("Scripting.FileSystemObject") 'open the user file Set objTextFile = objFSO.OpenTextFile(strINIFile) 'read the whole file If Not objTextFile.AtEndOfStream Then strFileText = objTextFile.ReadAll 'split the file into an array. aDataFile = Split(strFileText, vbCrLf) 'loop through each item in the array For nF = 0 to Ubound(aDataFile) If Left(aDataFile(nF), Len(strKey)+1)=strKey & "=" Then aDataFile(nF) = strKey & "=" & strValue bFound = True Exit For End If Next End If objTextFile.Close 'if entry was found then write back contents If bFound Then strFileText = Join(aDataFile, vbCrLf) Set objTextFile = _ objFSO.OpenTextFile(strINIFile, ForWriting ) objTextFile.Write strFileText Else 'entry not found, add new entry to end of file Set objTextFile = _ objFSO.OpenTextFile(strINIFile, ForAppending ) objTextFile.WriteLine strKey & "=" & strValue End If objTextFile.Close End Sub

Discussion

The TextStreamObject's file manipulation methods have a number of limitations. You cannot open a file for reading and writing at the same time. You must first read the contents of a file, close the file, manipulate the contents, and write the contents out again.

The Solution script uses the Split function to break the lines of a text file into an array that is based on the carriage return/newline character. Each element of the array is checked for a matching key value and, if found, is changed to a specified value. If the value is not found, it is appended to the end of the file.

Next, the array is converted back to a string using the Join function and written back to the source text file.

This method is useful for small files but it is less practical for larger ones because of the memory issues that are involved with reading the file, converting to an array, and writing to the source file.

A solution is to create a secondary temporary work file in which any change is written. This file is renamed to the source file upon completion of the operation and then deleted. In the following sample, the file bigfile.txt is converted to uppercase using a temporary work file:

Const TemporaryFolder = 2 Dim objFSO, strFilePath, objFolder, objSrcFile, objDestFile Dim strLine, strSourceFile Set objFSO = CreateObject("Scripting.FileSystemObject") strSourceFile = "d:dataigfile.txt" 'get a reference to the temporary file folder Set objFolder = objFSO.GetSpecialFolder(TemporaryFolder) 'create the path to the temporary file strFilePath = objFolder.Path & "" & objFSO.GetTempName 'create a temporary file and open the source file for processing Set objDestFile = objFSO.CreateTextFile(strFilePath) Set objSrcFile = objFSO.OpenTextFile(strSourceFile) strLine = objSrcFile.ReadLine 'loop through each line of source file and write to temp file Do While Not objSrcFile.AtEndOfStream 'read line from source and write to temp file - convert line to uppercase strLine = objSrcFile.ReadLine objDestFile.WriteLine UCase(strLine) Loop objSrcFile.Close objDestFile.Close 'copy temporary work file to source and delete temp file objFSO.CopyFile strFilePath, strSourceFile objFSO.DeleteFile strFilePath

The script uses the FSO's GetTempName method to return a randomly generated unique file name. Its syntax is as follows:

strTempName = objFSO.GetTempName

The example uses the FSO's GetSpecialFolder method to reference the temporary folder. It returns a Folder object for a specified systems folder. Its syntax is as follows:

Set objFolder = objFSO.GetSpecialFolder(nSpecialFolder)

The nSpecialFolder parameter determines the folder object to return. Valid values, along with constants that you can declare in your own code, are listed in Table 5-9.

Table 5-9: GetSpecialFolder Constants

CONSTANT

VALUE

DESCRIPTION

WindowsFolder

0

Windows directory

SystemFolder

1

Windows system directory (e.g., C:WinntSystem32)

TemporaryFolder

2

Windows temporary directory (e.g., C:Temp)

Категории