VBS脚本运行库手册之二 ——管理文件夹
(※管理文件夹磁盘的属性比如磁盘的剩余空间,磁盘的总额提供了一个全局的信息给系统管理员。但是,对于系统管理而言,磁盘的信息虽然是必须的,但是还不够。知道文件存储在哪个盘固然重要,但是你也需要知道文件是存储在哪个文件夹下的。此外许多的系统管理任务都是发生在文件夹级别的,比如复制,移动,删除和列举文件夹的内容。
FSO 可以返回一个磁盘上文件夹的全部信息。此外,FSO 提供了一系列的方法来完成诸如:复制、移动、删除文件夹的操作。
※
在微软的调用文件中,文件夹是 COM
对象。这就是说在你访问一个单独的文件夹的属性时,你必须去创建一个文件夹的对象reference,这个过程叫做绑定。你可以用FSO和GetObject的方法来绑定到一个文件夹。
当用 GetFolder 的时候,你必须:路径既可以写成本地路径也可以写成 UNC 路径(例如:\\accounting\receivables)。但是通配符不能出现在路径当中。此外,你不可以创建一个单独的对象 reference
来同时绑定到多个文件夹。例如,如下的脚本代码会产生一个错误:
objFSO.GetFolder("C:\FSO", "C:\Scripts")
如果你想针对多个文件夹同时工作,你要么用 WMI 或者用针对每个文件夹创建单独的对象reference。
在设置的时候 Set 这个关键词是必须的,因为你要标识这个对象 reference 变量。
例如下面的脚本绑定文件夹 C:\FSO
1
2
虽然通配符是不允许的,但是你可以用点来关联到当前的文件夹(.),你可以用点点(..)来绑定到父文件夹,用 \
绑定到根文件夹。例如如下代码语句绑定到当前的文件夹:
Set objFolder = objFSO.GetFolder(".")
※检验文件夹是否存在
许多的文件夹的操作包括复制、移动、删除需要特定的文件夹存在才可以对其进行操作。毕竟,脚本不能复制、移动、删除这些不存在的文件夹,如果一个脚本尝试去对一个不存在的文件夹执行类似的操作,那么会报错“path not found”。为了避免这样的问题发生,你可以用 FolderExists 方法来在你绑定一个文件夹之前检查文件夹是否存在。FolderExists用一个简单的参数(文件夹路径)来返回一个 Boolean 值,如果文件夹存在,返回的值为 True,否则返回的值为 False。
例如,下例中列出的脚本,FolderExists 方法来检查文件夹 C:\FSO 是否存在。如果存在,脚本用 GetFolder 方法来绑定文件夹。如果不存在,脚本就弹出一个 message box 说:Folder does not exist.
1
2
3
4
5
6
7
※如何建立文件夹
你不可能永远都使用你现有的文件系统结构,从来不去更改你的文件系统结构。而事实上,文件系统是动态的,因为需要变动,现存的文件夹可能被删除,新的文件夹可能被创建。例如,你的单位在
file servers 上给用户提供空间,你需要在每个新用户来的时候创建一个新的文件夹给他。
FSO给脚本编写者提供了这样的能力,可以让你通过脚本来创建文件夹。例如在上例中脚本检查特定的文件夹是否存在,如果存在,脚本用 GetFolder 的的方法来绑定到这个特定的文件夹,如果不存在,脚本弹出一个消息框。虽然这个方法避免了脚本的失败,但是你或许更希望在文件夹不存在的时候来创建一个文件夹,而不是简单的报告说文件夹不存在。为了做到这点,首先创建一个 FSO 对象实例,然后用CreateFolder 方法,将文件夹的完成路径作为参数,例如,下面脚本用这个方法来创建一个新的文件夹 C:\FSO
1
2
如果文件夹存在,那么会报错说”file exists”。基于此,你需要在创建文件夹的之前检查文件对象是否存在。
Note:FSO 只能在本地创建文件夹。如果你想在远程的计算机上创建文件夹,你需要用到
※
当你要删除文件夹时,例如你用文件服务器存储每一个员工的数据,当这个员工离开单位时,他的文件夹将被删除。这保证了文件服务器上的磁盘空间,同样,你或许用一个脚本来创建一个文件夹来存储临时文件,当脚本执行完毕的时候,你会删除这个临时的文件。DeleteFolder方法使你可以删除文件夹和文件夹下的所有文件。DeleteFolder需要一个单独的参数:文件夹的完全路径。例如下面脚本用来删除C:\FSO 和其它所有的东西。
1
2
这个方法会立即删除所有的文件,它不会让你确认是否需要删除就将其扔到垃圾筒。
※使用通配符(Wildcards)删除文件夹
脚本的最大的一个优点就是作为一个管理工具,脚本操作可以同时删除许多个项目。例如你可以用脚本的一个单独的操作就可以删除所有的文件和文件夹,而不用一个一个去删除了。
objFSO.DeleteFolder("C:\FSO\S*")
下面这个脚本用来删除以 su 开头的文件夹,就是说 subfolder1,subfolder2 会被删除。
objFSO.DeleteFolder("C:\FSO\Su*")
通配符只能放在文件路径的最末尾。
例如如下代码将通配符放在路径的中间,会报错:path not found
objFSO.DeleteFolder("C:\*\Subfolder1")
※复制文件夹及文件夹下的内容
复制文件夹和文件夹当中所有数据能力的对于系统管理任务来说非常重要。有时你需要复制文件夹来创建备份,在计算机 A 和计算机 B 上有同样的文件夹,如果计算机 B 意外的down掉之后,你就不怕数据丢失了。在其它的时候,你或许希望将含有特定文件的文件夹复制到很多台计算机上。用脚本来向各个计算机复制这个文件夹比手工复制高效的多。
1、CopyFolder 方法允许你复制一个文件夹到另外一个地方。当不用通配符的时候,这个CopyFolder 的方法和命令 Xcopy /E 命令一样:它拷贝所有的文件和子文件夹,包括空的文件夹。这个命令需要两个参数:源文件夹->这个文件夹可以被确定为本地路径(C:\Script)或者为 UNC 路径(\\helpdesk\scripts)。目标文件夹->这个文件夹也可以是本地文件夹和 UNC路径。如果目标文件夹不存在,那么将自动创建一个文件夹。此外这个方法有个可选的参数:Overwrite,当这个参数存在时,默认的情况下脚本会覆盖已经存在的目标文件夹。
在下例中用 CopyFolder 的方法来复制文件夹 C:\scripts 到 c:\FSO 并且复写目标文件夹。注意,这个的结果不是 C:\FSO\Scripts 而是 C:\FSO 下有和 C:\Scripts 有同样的文件。如果你想更改文件夹叫 C:\FSO\Scripts,你应该将目标文件夹改为 C:\FSO\Scripts
1
2
3
Note:因为这个 CopyFolder 是一个单独的操作,你没有办法来跟踪它的进程。你只是需要简单的等待操作的结束。如果你想监视 copy
命令的过程,你应该用 shell 应用程序。
※使用通配符(Wildcards)复制文件夹
用这个CopyFolder 命令也可以拷贝所有文件夹和子文件夹下的文件。这样可能导致一个问题,如果只是想拷贝 C:\FSO
下的文件,而不是想拷贝C:\FSO\Subfolder1,C:\FSO\Subfolder2,C:\FSO\Sbufolder3 下的文件。
可是,不幸的是这里没有直接的办法来不拷贝子文件夹中的文件而只是拷贝父文件夹中的文件,你可以用通配符来限制子文件夹的拷贝。例如如下的脚本代码只是拷贝以 log
字母开头的文件夹。但是,你用通配符的时候就只是拷贝那些符合特定要求的文件夹才被拷贝:
objFSO.CopyFolder "C:\Scripts\Log*" , "C:\Archive", True
当上面的脚本代码执行的时候,C:\Scripts\logs,C:\Scripts\Logfiles 被拷贝了,包括它们的文件和子文件夹中的文件。但是,在
C:\Scripts 的文件没有被拷贝。当你用 CopyFolder
方法的时候,你不能只是拷贝文件夹中的文件,而不拷贝子文件夹中的蚊子。如果你想只是拷贝文件而不拷贝子文件夹的文件,你可以应用 CopyFile 方法。
※移动文件夹
当你复制一个文件夹从一个地方到另外一个地方的时候,你以复制结束而告终。有时候这个正是你想要的,但是有的时候,你不需要两份文件的信息,你或许希望将文件夹从计算机
A 移动到计算机 B,或者从硬盘 C 移动到硬盘
D。移动工作总会移动到特定磁盘的剩余空间上。例如你或许会周期的将很少访问的文件夹移动到存档磁盘中。此外你或许有一个脚本来监视本地计算机的信息,当监视结束的时候,你需要将它上传到服务器,然后将本地文件删除,然后本地计算机就开始下一次的监视。
MoveFolder 需要两个参数:
1、Source folder 源文件夹,可以是本地路径或者是 UNC 路径。
2、Destination folder 目标文件夹,这个文件系也可是本地或者 UNC 路径。
如果你的目标文件夹不存在,那么移动是成功的。如果目标文件夹存在,那么不成功。你不能用这个 MoveFolder 的方法来覆盖一个文件夹。下例脚本中,移动本地的文件夹 C:\Scripts 到一个共享的文件夹 \\helpdesk\management
1
2
注意用 MoveFolder
方法当脚本失败后不能循环操作。例如,假如你的网络连接在脚本将文件从一个计算机移动到另外一个计算机完成前失败了,那么很有可能你一些文件在计算机 A 上,另外一些文件在计算机 B 上,也有可能在移动的过程中丢失一些文件。因为这个 MoveFolder 的方法无法让脚本恢复到以前状态。
因为如此,你或许需要两个方法来完成文件在网络中的移动:CopyFolder 和 DeleteFolder。你可以用 CopyFolder 来将文件从计算机 A 移动到计算机 B。当复制的操作结束之后,你用DeleteFolder 来删除计算机 A 上的文件,当复制操作失败的时候,你可以确保你的文件还在你的计算机上。
※重命名文件夹
在FSO中没有提供RenameFolder 方法重新命名文件夹。但是可以用
MoveFolder方法来将文件夹移动到相对同样的位置,例如假如有文件夹路径如下:
C:\Scripts\PerformanceMonitoring\Servers\Domain Controllers\Current Logs
如果你用 Windows 浏览器来更改文件夹的名字,那么文件夹还是它本身
C:\Scripts\PerformanceMonitoring\Servers\Domain Controllers\Archived Logs
MoveFolder 的方法可以让你完成同样任务,你将
C:\Scripts\PerformanceMonitoring\Servers\Domain Controllers\Current Logs作为源路径,将 C:\Scripts\PerformanceMonitoring\Servers\Domain Controllers\Archived Logs作为目标路径。这样的结果和在 windows 浏览器中更改文件夹的名字效果是样的。
例如,下例中的脚本将文件夹C:\FSO\Samples更改为C:\FSO\Scripts在脚本运行之前,Sample 是C:\Scripts的文件夹,在脚本运行之后,就是C:\FSO的子文件夹了。此外Scripts (FSO 下的)含有原来 Sample
所有的文件和子文件。
1
2
※获得文件夹属性
因为文件夹是一个 COM 对象,它们的属性可以被获得和列举出来,为了列举详细的文件夹信息,你可以用文件夹对象,它是 FSO
的组件之一。文件夹对象的属性列举在了下表中。
Attributes
DateCreated
DateLastAccessed
DateLastModified
Drive
Files
IsRootFolder
Name
ParentFolder
Property
Path
ShortName
ShortPath
Size
SubFolders
Type
※列举文件夹的属性
为了得到一个文件夹的属性,一个脚本必须:
1.创建一个 FSO 实例
2.用 GetFolder 的方法绑定特定文件夹
3.用 Echo 的方法显示属性。
当你对一个文件夹的属性进行操作的时候,注意文件的属性和子文件夹的属性是以集合的形式返回的,不是单独返回一个的。此外Attributes 属性返回一个属性值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
※管理文件夹的属性
文件系统支持属性的定义。就是文件夹中和文件夹名字和文件夹大小无关的信息。例如如果你在 Windows 浏览器中右击某个数据夹的时候,点 Properties 你就可以访问文件夹的属性了。
FSO 可以返回几个关于文件夹信息的重要属性。这些属性和相应的值,列举在下表中:
Hidden
System
Directory
夹读有这个值,最小位 16。
Archive
如果这个值 enabling 表示文件夹在下一次增量备份中会备份。如果
是disabling 表示不在下一次增量备份中备份
Compressed
虽然这些看起来很简单,但是从
FSO返回的数据看起来会让你感到很迷惑。例如,你返回一个文件夹的属性值,你或许会看到20,但是这个值并不是像上面一样的标准值。此外,你可能会获得一个单独的值,虽然这个文件夹有说有的属性。这种情况是,脚本并不是返回如
2,4,16,32,2048 这样的值,而只是返回一个 2102。这是因为这些值是以位图的形式显示的。
Note:对于属性值,它返回和存储的数据是以位图的形式的。对于位图你应该不会奇怪,比如后缀名为.bmp 的图形文件
位图看起来就是一系列的开关。如果特定的开关是关闭的,那么这个开关的值就是0,如果是开启的,比如文件夹对象吧,它就具有上表中所列出的值。而位图的值就是这些开关的值的总和。如果你用脚本查询这个文件夹的属性,脚本就返回一个值为 16.
与其相反,如果有三个开关是开启的:隐藏(值是2),Directory(值是16),压缩(值是 2048).那么这个位图的值应该是 2+16+2048,或者值是 2066。这个也是用脚本查询的时候返回的值。位图被设计成只是有一种办法来获取特定的值。得到值 2066 的方法只有一个就是压缩和隐藏。你不可能通过别的数学方法来算得这样的值。
这个设计可以返回值并且决定哪个开关没有开哪个没有开。这个可以允许你来判断文件夹的哪个属性设定了。如果你得到了这个 2066
的值,那么它的属性就是隐藏压缩的文件夹。幸运的是,你不必去作任何单独的数字运算,你可以用逻辑与 AND 操作来决定哪个开关是否是on 还是 off。例如如下代码查询文件夹是否是隐藏的,如果是回显一个信息框: Hidden folder
If objFolder.Attributes AND 2 Then
End If
或者:
下列脚本先绑定文件夹 C:\FSO,然后回显文件夹属性:
(译者注:这个其实是挨个匹配的,所以你要是测试了两个属性,它都会显示出来的。)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
※改变文件夹属性
文件夹的每个属性可以看成一个个开关,如果关于隐藏的开关是ON 的,那么这个文件夹就是隐藏的,如果这个开关是 OFF
的,那么这个文件夹就不是隐藏的,你可以选择打开或者关掉它们,对于文件夹的属性也是如此:对于其它的开关,你可以将属性设置为开或者设置为关,你可以用脚本来控制这些开关的,最简单的控制属性开关的办法是用如下的程序:
1. 用 GetFolder 的方法来绑定到一个文件夹。
2. 检查你需要更改的值。例如你想隐藏一个文件夹,看这个文件夹是否是已经隐藏了
3. 如果这个文件夹是隐藏的,用 XOR 操作来将开关转换成非隐藏的。如果这个文件夹不是隐藏的,注意不要用
XOR,如果你用了,开关会被触发,文件夹会中止于隐藏。例如,下列脚本用 AND 来判断文件夹 C:\FSO 的隐藏属性开关是否开着。如果它是开的,脚本用 XOR
操作来将开关关闭来显示文件夹。
1
2
3
4
5
除非很少的一些情况以外,文件夹用来作为单独存放文件的地方。有时候,这些文件夹是系统需要的。例如操作系统希望在特定的文件夹内找到特定的文件。在其它的一些时候,文件夹是系统管理员管理计算机的一种工具也是用户管理文件的工具。系统管理员可能希望将脚本放在叫做Scripts
的文件夹,将一些 trouble-shooting 的工具放在叫做 Diagnostic Tools 的文件夹。用户或许将他们预算信息放在叫做 Budgets
的文件夹,而将薪水的信息放在叫做 Timecards
的文件夹。当然,文件夹一般是限制使用的,你必须知道这个文件夹是存放的是什么文件。系统管理员需要知道是不是有个特定的脚本存在 C:\Scripts 文件夹中,用户需要知道是不是有个特定的窗体存在C:\Budgets 的文件夹中。文件夹对象包含了一些属性可用来返回存储在文件夹内文件集合的信息,为了得到这些信息,你的脚本必须:
1. 创建一个 FSO 对象实例。
2. 用 GetFolder 的方法来绑定到一个适当的文件夹。
3. 设置一个对象 reference 来指向文件夹的属性
4. 用 For Each 循环来列举出所有的文件和他们的属性。脚本不必去绑定到每一个单独的文件去获得文件的信息。
在下列脚本中返回在文件夹 C:\FSO 下所有文件的信息并且回显他们的名字和大小:
1
2
3
4
5
6
对于大多数返回的集合来说,你不能控制输出信息的顺序。就是说你不能将输出的格式定义为按照名字,按照大小或者其它别的原则。如果你想让输出的东西按照特定的格式,你就必须将他们拷贝到数组,目录或者一个 disconnected recordset 然后将他们分类排列。