搜索
您的当前位置:首页正文

VBS脚本编程简明教程

2020-07-14 来源:好走旅游网
2018年普通高等学校招生全国1卷

第一章 VBS脚本编程简明教程

第一节 ◎Vbs脚本编程简明教程之一—为什么要使用Vbs?

在Windows中,学习计算机操作也许很简单,但是很多计算机工作是重复性劳动,例如你每周也许需要对一些计算机文件进行复制、粘贴、改名、删除,也许你每天启动计算机第一件事情就是打开WORD,切换到你喜爱的输入法进行文本编辑,同时还要播放优美的音乐给工作创造一个舒心的环境,当然也有可能你经常需要对文本中的某些数据进行整理,把各式各样的数据按照某种规则排列起来……。这些事情重复、琐碎,使人容易疲劳。

第三方软件也许可以强化计算机的某些功能,但是解决这些重复劳动往往事倍功半,我也尝试过使用计算机语言编写程序来解决这些问题,但是随之而来的命令、语法、算法、系统框架和类库常常让我觉得这样是否有必要,难道就是因为猪毛比较难拔,所以我就要去学习机械,为自己设计一个拔猪毛机(?)吗?

Vbs是一种Windows脚本,它的全称是:Microsoft Visual Basic Script Editon.(微软公司可视化BASIC脚本版),VBS是Visual Basic的的一个抽象子集,是系统内置的,用它编写的脚本代码不能编译成二进制文件,直接由Windows系统执行(实际是一个叫做宿主host的解释源代码并执行),高效、易学,但是大部分高级语言能干的事情,它基本上都具备,它可以使各种各样的任务自动化,可以使你从重复琐碎的工作中解脱出来,极大的提高工作效率。

我个人认为Vbs脚本其实就是一种计算机编程语言,但是由于缺少计算机程序设计语言中的部分要素,对于事件的描述能力较弱,所以称为脚本,它最方便的地方就是提供了对COM对象的简便支持。那么什么是COM对象呢?

我这样理解,COM对象就是一些具有特定函数功能项程序模块,他们一般以ocx或者dll作为扩展名,你只要找到包含有你需要的功能的模块文件,并在脚本中规范的引用,就可以实现特定的功能,也就是说Vbs脚本就是调用现成的“控件”作为对象,用对象的属性和方法实现目的,完全免去了编写代码、设计算法等等麻烦。说白了,我不是觉得拔猪毛麻烦么?我发觉xx机(比如真空离心器)有一个功能可以实现脱毛,ok,我把它拿来给猪脱毛。什么?大材小用?太浪费资源了?天哪,那是计算机芯片的事情,死道友不死贫道,反正我的事情是方便快速的解决了,这就行了。

最方便的是它甚至不需要专门的开发环境,在你的计算机中,只要有notepad,就可以编写Vbs脚本了,并且可以直接执行。

第二节 ◎Vbs脚本编程简明教程之二—如何开始第一个Vbs脚本?

就像多数计算机教程一样 ,我们从“Hello World!”程序开始我们的练习。什么?不知道是什么意思?就是说大部分的计算机程序设计教程开篇入门都是编写一个小程序,执行这个程序的结果就是在计算机的屏幕上或者dos窗口中显示

页脚内容91

2018年普通高等学校招生全国1卷

一行文字:Hello World!好了,我们开始吧。

打开你的“记事本”程序,在编辑窗口填写: msgbox \"Hello World!\"

然后用鼠标单击“文件”菜单,单击“保存”,把“保存在”一栏设为桌面,在“文件名”一栏中填写kk.vbs,单击“保存”就可以了。然后最小化“记事本”窗口,在桌面上寻找你刚刚保存的kk.vbs,然后双击。看到弹出的对话框了没有,单击“确定”,对话框消失了。难看了点,不过确实是你编写的第一个脚本程序。

说 明之一:上面的操作中,保存位置放在桌面,仅仅是为了执行方便,你保存到其他的地方完全没有问题,只要你知道你保存在什么地方就可以了,什么?是废话,自 己保存的当然知道保存在那里了。不,自己保存的文件自己找不到的人我见的多了去了。文件名你可以随意填写,不一定非要写kk,只要符合Windows的文件命名规则就可以了,但是扩展名必须是vbs,什么?不知道什么是扩展名?就是文件名中“.”后的那部分,简单说,就是vbs脚本文件命名时必须是:xxx.vbs,其中xxx你随意。

说明之二:在记事本编辑窗口中写的这行是什么意思?

Msgbox是VBS内 建的函数,每一个函数都可以完成一定的功能,你只需要按照语法要求,在函数的相应部分填写相应的内容就可以了,这部分内容我们称为参数,当然函数执行的结 果我们称为返回值,一个函数可以有返回值也可以没有,可以有参数也可以没有。你不用了解函数是怎么运作的,只要了解这个函数能干什么就行了。

Msgbox语法:msgbox \"对话框内容\对话框的标题\" 你不妨用记事本打开刚才的文件在编辑窗口中输入: msgbox \"Hello World!\" , , \"系统提示\" 执行一下,看看效果和位置。

说明之三:如果执行失败,看看你的标点符号,所有的标点符号必须是在英文状态下输入的。

当然,这个脚本实在是太简单了,甚至连最简单的交互都没有,所以你可以把脚本这样修改一下:

Dim name

name=Inputbox(\"请输入你的名字:\名称\") Msgbox name, , \"您的名字是\"

保存执行一下,看到弹出的对话框了么?填入你的名字,点确定,看到结果了吗?

说明之一:第一句是定义变量,dim是定义变量的语句 其格式为:dim变量1,变量2……,

Vbs只有一种变量类型,所以不用声明变量类型。系统会自动分辨变量类型。 说明之二:inputbox是VBS内建的函数,可以接受输入的内容,其语法格式为:

Inputbox(\"对话框内容\对话框标题\")

第二句的意思是接受用户的输入,并把输入结果传递给变量name。

好了,到此脚本基本的输入输出函数都有了,已经可以完成一些比较简单的功能了,你可以编写一个简单的脚本,然后拷贝的“程序”—>“启动”中,然后重新启动计算机看看结果。

页脚内容91

2018年普通高等学校招生全国1卷

第三节 ◎Vbs脚本编程简明教程之三—Vbs的基本语法(牢

记)

VBScript基础知识 一、变量

1、所有单引号后面的内容都被解释为注释。

2、在VBScript中,变量的命名规则遵循标准的命名规则,需要注意的是:在VBScript中对变量、方法、函数和对象的引用是不区分大小写的。在申明变量时,要显式地申明一个变量,需要使用关键字DIm来告诉VBScript你要创建一个变量,并将变量名称跟在其后。申明多个同类型变量,可以用逗号分隔。注意:VBScript中不允许在申明变量的时候同时给变量赋值。但是允许在一行代码内同时对两个变量进行赋值,中间用冒号分隔。

3、你可以使用OptionExplicit来告诉宿主变量必须先声明后使用。

4、VBScript在定义时只有一种变量类型,在实际使用中需要使用类型转换函数来将变量转换成相应的变量类型。

Cbool函数将变量转换成布尔值;

Cbyte函数将变量转换为0到255之间的整数。

Ccur函数、Cdbl函数和Csng函数将变量转换为浮点数值,前者只精确到小数点后四位,后两者要更加精确,数值的范围也要大的多。

Cdate函数将变量转换为日期值。

Cint函数和Clng函数将变量转换为整数,后者的范围比前者要大的多。 Cstr函数将变量转换为字符串。 二、数组

数组的定义与变量非常类似,只需要在变量后描述这个数组的个数和维数。需要注意的是:数组的下标总是从0开始,而以数组定义中数值减一结束。也就是说你以要定义一个有十个数据的数组,将这样书写代码:dImarray(9),同样,当你要访问第五个元素时,实际的代码是array(4)。当然,你可以通过不指定数组的个数和维数来申明动态数组。等到数组的个数和维数固定后,使用关键字redim来改变数组。注意,在改变数组的大小时,数组的数据会被破坏,使用关键字preserve来保护数据。例如:

RedIm空格preserve空格array括号个数逗号维数括号 三、操作符

在VBScript运算符中,加减乘除都是我们常用的符号,乘方使用的是 ^,取模使用的Mod。

在比较操作符中,等于、小于、大于、小于等于、大于等于都与我们常用的符号是一致的,而不等于是小于和大于连用。

逻辑运算符为:和操作—>AND 非操作—>NOT 或操作—>OR; 你可以使用操作符 +和操作符 &来连接字符串,一般使用&操作符;

另外还有一个比较特殊的操作符Is用来比较对象,例如按钮对象,如果对象是同一类型,结果就是真,如果对象不是同一类型,结果就是假。

四、条件语句主要有if……then语句和selectcase语句两种形式 在if……then语句中,其基本形式为:

页脚内容91

2018年普通高等学校招生全国1卷

If 条件 then

处理条件的语句; …… Endif

基本形式只能对单个条件进行验证,如果有两个条件,则需要在基本形式中添加单行语句else,如果还有更多的条件需要验证,则需要添加语句

Elseif条件 then 处理条件语句

在selectcase语句中,其基本形式为: Select case 变量 Case 条件值 处理条件语句

并对上两句进行重复 最后一句应为 case else 处理语句

当然不要忘记将条件结束语句End select放在最后一行

注意:在执行字符串比较时,需要特别注意大小写,一般情况下,我们在比较前,使用lcase函数将字符串转换成小写,使用ucase函数将字符串转换成大写大写。

五、循环控制语句

循环控制语句有for……next循环、for……each循环、do……while循环、do……until循环、while循环五种形式。

在使用循环控制语句前,首先要对循环条件进行判断,如果循环次数是有固定次数的,那么使用For……next循环,其结构为:

For 计数器变量=开始计数值 to 最后计数值 执行循环体 Next

如果是需要对数组或对象集合中的每一个元素进行判断,则需要使用for……each循环,其结构为:

For each 循环计数变量 in 要查看的对象或数组 执行处理语句 Next

注意:在上述两种循环中随时可以使用exit for来退出循环

如果你希望在条件满足时执行一段代码则使用do……while语句,结构为: Do while 条件 执行循环体 Loop

如果你希望在条件不满足时执行代码,则使用do……until语句,结构为: Do until 条件 执行循环体 Loop

当然,在这两种循环语句中,你可以使用exit do来退出循环 最后一种循环语句是条件满足时一直执行循环,

页脚内容91

2018年普通高等学校招生全国1卷

While 条件 执行循环体 Wend

六、使用过程

常用的过程有两种,一种为函数,给调用者返回值,一种为子程序,无返回值,还有一种叫事件的特殊子程序,用的比较少。

函数的基本定义方法为:

Function 函数名称(参数列表) 函数代码

函数名称=某值 ‘用来返回值 end function

子程序一些都类似,不过没有返回值

注意:尽管在定义子程序的时候,参数列表要加括号,但在调用子程序的时候,参数列表不加括号,括号只在函数中使用。另外,子程序不能在表达式中使用。

而函数只能出现在赋值语句的右边,或者表达式中,函数不能直接使用,如果必须直接使用函数,则必须使用call语句调用,并取消返回值。

第四节 ◎Vbs脚本编程简明教程之四—如何利用Vbs运行外部程序?

Vbs只提供了编程的一个基本框架,用户可以使用Vbs来定义变量、过程和函数,vbs也提供了一些内部函数和对象,但是Vbs没有提供任何命令来访问Windows系统内部的部件,但是值得庆幸的是,Vbs虽然不能自己完成这些任务,但是它提供了一条极为方便、功能也相当强的命令——CreateObject,这条命令可以访问windows系统内安装的所有com对象,并且可以调用这些部件中存放的命令。

于是问题解决了,比如说,我手头有1000个小文本,我首先要对每一个文本的语法进行查错和修改,然后按照预先定义好的规则对这些文本进行排序,最后将这些文本合并成为一个文件。正常情况下,我们需要把打开第一个小文本,然后把它复制到WORD中,然后利用里面的除错功能进行除错和修改,然后再导入到EXCEL中进行排序,将这个过程重复1000遍,然后再将所有得到的文本复制到一个大文本中。实在是太枯燥、工作量太大了。有了Vbs和CreateObject,问题得到解决,我只需要找到相应的模块,调用相应的功能就可以了,作为脚本,把一个枯燥的过程重复1000次,本就是它的拿手好戏。

好了,我们走入正题,从最简单的——只启动一个程序开始。 WSH也就是用来解析Vbs的宿主,本身包含了几个个常用对象: 1、Scripting.FileSystemObject —> 提供一整套文件系统操作函数 2、Scripting.Dictionary —> 用来返回存放键值对的字典对象

页脚内容91

2018年普通高等学校招生全国1卷

3、Wscript.Shell —> 提供一套读取系统信息的函数,如读写注册表、查找指定文件的路径、读取DOS环境变量,读取链接中的设置

4、Wscript.NetWork —>

提供网络连接和远程打印机管理的函数。(其中,所有Scripting对象都存放在SCRRUN.DLL文件中,所有的Wscript对象都存放在WSHOM.ocx文件中。)

现在我们需要的是第三个对象,好了,让我们先连接一下对象看看,在记事本的编辑窗口中输入:

Set objShell = CreateObject(“Wscript.Shell”) objShell.Run “notepad”

同样,保存执行。那么看到了一个什么样的结果呢?在桌面上又打开了一个记事本。

说明之一:Set是Vbs指令,凡是将一对象引用赋给变量,就需要使用set关键字。那么什么是对象引用呢?凡是字符串、数值、布尔值之外的变量都是对象引用。Objshell是变量名,可以随意修改。

说明之二:反是正确引用的对象,其本身内置有函数和变量,其引用方法为在变量后加“.”,后紧跟其实现功能的函数就可以了。Objshell.run

的意思就是调用Wscript.shell中的运行外部程序的函数——run,notepad是记事本程序的文件名。当然你也可以改成“calc”,这是计算器的文件名,winword是word的文件名,等等吧,所有可执行文件的文件名都可以。但是需要注意的是,如果你要执行的可执行文件存放的地方不是程序安装的常用路径,一般情况下,需要提供合法的路径名,但是run在运行解析时,遇到空格会停止,解决的方法是使用双引号,例如:在我的机器上运行qq,代码为:

objshell.run \"\"\"C:\\Program Files\\QQ2006\\QQ.exe\"\"\" ‘注:三个引号 好, 我们再进一步,启动两个程序会如何呢? 输入如下代码:

Set objShell = CreateObject(“Wscript.Shell”) objShell.Run “notepad” objShell.Run “calc”

执行会如何呢?两个程序基本上同时启动了。如果我们需要先启动notepad再启动calc将如何呢?很简单在需要顺序执行的代码后加 , , True参数就可以了。

好了输入代码:

Set objShell = CreateObject(“Wscript.Shell”) objShell.Run “notepad” ,,true objShell.Run “calc”

看看执行的结果怎么样吧!

总结:run函数有三个参数,第一个参数是你要执行的程序的路径,第二个程序是窗口的形式,0是在后台运行;1表示正常运行;2表示激活程序并且显示为最小化;3表示激活程序并且显示为最大化;一共有10个这样的参数我只列出了4个最常用的。

第三个参数是表示这个脚本是等待还是继续执行,如果设为了true,脚本就会等待调用的程序退出后再向后执行。

其实,run做为函数,前面还有一个接受返回值的变量,一般来说如果返回为0,表示成功执行,如果不为0,则这个返回值就是错误代码,可以通过这个代码找出相应的错误。

页脚内容91

2018年普通高等学校招生全国1卷

第五节 ◎Vbs脚本编程简明教程之五—错误处理

引发错误的原因有很多,例如用户输入了错误类型的值,或者脚本找不到必需的文件、目录或者驱动器,我们可以使用循环技术来处理错误,但是VBS本身也提供了一些基本技术来进行错误的检测和处理。

1、最常见的错误是运行时错误,也就是说错误在脚本正在运行的时候发生,是脚本试图进行非法操作的结果。例如零被作为除数。在vbs中,任何运行时错误都是致命的,此时,脚本将停止运行,并在屏幕上显示一个错误消息。你可以在脚本的开头添加

On Error Resume Next

这行语句可以告诉vbs在运行时跳过发生错误的语句,紧接着执行跟在它后面的语句。

发生错误时,该语句将会把相关的错误号、错误描述和相关源代码压入错误堆栈。

2、虽然On Error Resume

Next语句可以防止vbs脚本在发生错误时停止运行,但是它并不能真正处理错误,要处理错误,你需要在脚本中增加一些语句,用来检查错误条件并在错误发生时处理它。

vbscript提供了一个对象err对象,他有两个方法clear,raise,5个属性:description,helpcontext,helpfile,number,source

err对象不用引用实例,可以直接使用,例如: on error resume next a=11 b=0 c=a/b

if err.number<>0 then

wscript.echo err.number & err.description & err.source end if

第六节 ◎Vbs脚本编程简明教程之六—修改注册表

Vbs中修改注册表的语句主要有: 1、读注册表的关键词和值:

可以通过把关键词的完整路径传递给wshshell对象的regread方法。例如: set ws=wscript.createobject(\"wscript.shell\")

v=ws.regread(\"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\nwiz\")

wscript.echo v 2、写注册表

使用wshshell对象的regwrite方法。例子:

path=\"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\\"

set ws=wscript.createobject(\"wscript.shell\")

页脚内容91

2018年普通高等学校招生全国1卷

t=ws.regwrite(path & \"jj\ 这样就把

HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\jj这个键值改成了hello.不过要注意:这个键值一定要预先存在。

如果要创建一个新的关键词,同样也是用这个方法。

path=\"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\run\\sssa2000\\love\\\"

set ws=wscript.createobject(\"wscript.shell\") val=ws.regwrite(path,\"nenboy\") val=ws.regread(path) wscript.echo val 删除关键字和值

使用regdelete方法,把完整的路径传递给regdelete就可以了 例如

val=ws.regdel(path)

注意,如果要删除关键词的值的话 一定要在路径最后加上“\\”,如果不加斜线,就会删除整个关键词。

当然,从现在的角度看,还是使用WMI的注册表处理功能也许更好些。

◎windows的常用自动启动项

Windows启动时通常会有一大堆程序自动启动。不要以为管好了“开始→程序→启动”菜单就万事大吉,实际上,在Windows

XP/2K中,常见的两个文件夹和八个注册键都可以使程序实现自动启动。 一、当前用户专有的启动文件夹:这是许多应用软件自动启动的常用位置,Windows自动启动放入该文件夹的所有快捷方式。用户启动文件夹一般在:\\Documents

and Settings\\<用户名字>\\“开始”菜单\\程序\\启动,其中“<用户名字>”是当前登录的用户帐户名称。

二、对所有用户有效的启动文件夹:这是寻找自动启动程序的第二个重要位置,不管用户用什么身份登录系统,放入该文件夹的快捷方式总是自动启动——这是它与用户专有的启动文件夹的区别所在。该文件夹一般在:\\Documents

and Settings\\All Users\\“开始”菜单\\程序\\启动。

三、Load注册键:也能够自动启动程序。位置:HKEY_CURRENT_USER\\Software\\Microsoft\\WindowsNT\\CurrentVersion\\Windows\\load。

四、Userinit注册键:位置:HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\WindowsNT\\CurrentVersion\\Winlogon\\Userinit。这里也能够使系统启动时自动初始化程序。通常该注册键下面有一个userinit.exe,这个键允许指定用逗号分隔的多个程序,例如“userinit.exe,OSA.exe”(不含引号)。

五、Explorer\\Run注册键:和load、Userinit不同,Explorer\\Run键在HKEY_CURRENT_USER和HKEY_LOCAL_MACHINE下都有,具体位置是:

页脚内容91

2018年普通高等学校招生全国1卷

HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policie*\\**plorer\\Run,和HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policie*\\**plorer\\Run。

六、RunServicesOnce注册键:RunServicesOnce注册键用来启动服务程序,启动时间在用户登录之前,而且先于其他通过注册键启动的程序。RunServicesOnce注册键的位置是:HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\RunServicesOnce,和HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunServicesOnce。

七、RunServices注册键:RunServices注册键指定的程序紧接RunServicesOnce指定的程序之后运行,但两者都在用户登录之前。RunServices的位置是:HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\RunServices,和HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunServices。

八、RunOnce\\Setup注册键:RunOnce\\Setup指定了用户登录之后运行的程序,它的位置是:HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\\Setup,和HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce\\Setup。

九、RunOnce注册键:安装程序通常用RunOnce键自动运行程序,它的位置在HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce和HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce。HKEY_LOCAL_MACHINE下面的RunOnce键会在用户登录之后立即运行程序,运行时机在其他Run键指定的程序之前。HKEY_CURRENT_USER下面的RunOnce键在操作系统处理其他Run键以及“启动”文件夹的内容之后运行。如果是XP,你还需要检查一下HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnceEx。

十、Run注册键:Run是自动运行程序最常用的注册键,位置在:HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run,和HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run。HKEY_CURRENT_USER下面的Run键紧接HKEY_LOCAL_MACHINE下

第七节 ◎Vbs脚本编程简明教程之七—FSO的常见对象和方法

文件系统是所有操作系统最重要的部分之一,脚本经常会需要对文件及文件夹进行访问和管理,在Vbs中对桌面和文件系统进行访问的顶级对象是FileSystemObject(FSO),这个对象特别复杂,是vbs进行文件操作的核心。此节内容应了如指掌。

FSO包含的常见对象有:

Drive对象:包含储存设备的信息,包括硬盘、光驱、ram盘、网络驱动器

页脚内容91

2018年普通高等学校招生全国1卷

Drives集合:提供一个物理和逻辑驱动器的列表 File 对象:检查和处理文件

Files集合:提供一个文件夹中的文件列表 Folder对象:检查和处理文件夹

Folders集合:提供文件夹中子文件夹的列表 Textstream对象:读写文本文件 FSO的常见方法有:

BulidPath:把文件路径信息添加到现有的文件路径上 CopyFile:复制文件

CopyFolder:复制文件夹 CreateFolder:创建文件夹

CreateTextFile:创建文本并返回一个TextStream对象 DeleteFile:删除文件

DeleteFolder:删除文件夹及其中所有内容 DriveExits:确定驱动器是否存在 FileExits:确定一个文件是否存在 FolderExists:确定某文件夹是否存在

GetAbsolutePathName:返回一个文件夹或文件的绝对路径 GetBaseName:返回一个文件或文件夹的基本路径 GetDrive:返回一个dreve对象

GetDriveName:返回一个驱动器的名字 GetExtensionName:返回扩展名 GetFile:返回一个file对象

GetFileName:返回文件夹中文件名称 GetFolder:返回一个文件夹对象

GetParentFolderName:返回一个文件夹的父文件夹 GetSpecialFolder:返回指向一个特殊文件夹的对象指针

GetTempName:返回一个可以被createtextfile使用的随机产生的文件或文件夹的名称

MoveFile:移动文件

MoveFolder:移动文件夹

OpenTextFile:打开一个存在的文件并返回一个TextStream对象

第八节 ◎Vbs脚本编程简明教程之八—FSO中文件夹的基本操作

1、使用fso

由于fso不是wsh的一部分,所以我们需要建立他的模型 例如set fs=wscript.createobject(“scripting.filesystemobject”)

这样就建立了fso的模型。如果要释放的话也很简单,set fs=nothing 2、使用文件夹

在创建前,[作者:临汾市外事旅游局薛靖澜,转载请注明出处]我们一般需要

页脚内容91

2018年普通高等学校招生全国1卷

检查该文件夹是否存在例如:

dim fs,s //定义fs、s两个变量

set fs=wscript.createobject(“scripting.filesystemobject”) //fs为FSO实例 if (fs.folderexists(“c:\emp”)) then //判断c:\emp文件夹是否存在 s=”is available” else

s=”not exist”

set foldr=fs.createfolder(“c:\emp”) //不存在则建立 end if

删除: set fs=wscript.createobject(“scripting.filesystemobject”) fs.deletefolder(“c:\\windows”)

拷贝: set fs=wscript.createobject(“scripting.filesystemobject”) fs.copyfolder “c:\\data” “d:\\data”

注意:如果c:\\data 和d:\\data都存在,脚本会出错,复制也就会停止,如果要强制覆盖,使用fs.copyfolder “c:\\data” “d:\\data”,true

移动: set fs=wscript.createobject(“scripting.filesystemobject”) fs.movefolder “c:\\data” “d:\\data”

我们可以使用统配符,来方便操作:

例如, fs.movefolder :c:\\data\e*” , “d:\\working”

注意:在目的路径最后没有使用“\\” 也就是说我没有这样写: fs.movefolder c:\\data\e*” , “d:\\working\\”

这样写的话,如果d:\\working 目录不存在,windows就不会为我们自动创建这个目录。

注意:上面我们所举的例子都是在利用fso提供的方法,如果使用folder对象也完全是可以的:

set fs= wscript.createobject(“scripting.filesystemobject”) set f=fs.getfolder(“c:\\data”)

f.delete //删除文件夹c:\\data。如果有子目录,也会被删除 f.copy “d:\\working”,true //拷贝到d:\\working f.move “d:\emp” //移动到d:\emp 3、特殊文件夹

一般指的就是系统文件夹:\\windows\\system32, 临时文件夹,windows文件夹,在前几篇的时候,[作者:临汾市外事旅游局薛靖澜,转载请注明出处]我们提过一下:例如

set fs=wscript.createobject(“scripting.filesystemobject”) set wshshell=wscript.createobject(“wscript.shell”)

osdir=wshshell.expandenvironmentstrings(“%systemroot%”) set f =fs.getfolder(osdir) wscript.echo f

当然,还有简单的方法 那就是使用getspecialfolder() 这个方法使用3种值:

0 表示windows文件夹,相关常量是windowsfolder 1 系统文件夹,相关常量是systemfolder 2 临时目录,相关常量temporaryfolder

页脚内容91

2018年普通高等学校招生全国1卷

例如:

set fs=wscript.createobject(“scripting.filesystemobject”) set wfolder=fs.getspecialfolder(0) ‘返回windows目录 set wfolder=fs.getspecialfolder(1) ‘返回system32\\ set wfolder=fs.getspecialfolder(2)'返回临时目录

第九节 ◎Vbs脚本编程简明教程之九—妙用SendKeys简化重复操作

每次开机的时候,你想自动登陆你的QQ或者博客吗?巧妙使用VBS中的SendKeys命令(这个命令的作用就是模拟键盘操作,将一个或多个按键指令发送到指定Windows窗口来控制应用程序运行),可以极大的方便我们的常用操作。其使用格式为:

Object.SendKeys string其中:

Object:为WshShell对象,即脚本的第一行为: Set WshShell=WScript.CreateObject(\"WScript.Shell\") 将Object替换为WshShell

“string”:表示要发送的按键指令字符串,需要放在英文双引号中。它包含如下内容:

1.基本键:一般来说,要发送的按键指令都可以直接用该按键字符本身来表示,例如要发送字母“x”,使用“WshShell.SendKeys

\"x\"”即可。当然,也可直接发送多个按键指令,只需要将按键字符按顺序排列在一起即可,例如,要发送按键“cfan”,可以使用

“WshShell.SendKeys \"cfan\"”。 2.特殊功能键:对于需要与Shift、Ctrl、Alt三个控制键组合的按键,SendKeys使用特殊字符来表示:Shift— +;Ctrl — ^;Alt— %

如要发送的组合按键是同时按下Ctrl+E,需要用WshShell.SendKeys

\"^e\"”表示,如果要发送的组合按键是按住Ctrl键的同时按下E与C两个键,这时应使用小括号把字母键括起来,书写格式为“WshShell.SendKeys

\"^(ec)\"”,这里要注意它与“WshShell.SendKeys

\"^ec\"”的区别,后者表示组合按键是同时按住Ctrl和E键,然后松开Ctrl键,单独按下“C”字母键。

由于“+”、“^”这些字符用来表示特殊的控制按键了,如何表示这些按键呢?只要用大括号括住这些字符即可。例如,要发送加号“+”,可使用“WshShell.SendKeys

\"{+}\"”。另外对于一些不会生成字符的控制功能按键,也同样需要使用大括号括起来按键的名称,例如要发送回车键,需要用“WshShell.SendKeys

\"{ENTER}\"”表示,发送向下的方向键用 “WshShell.SendKeys \"{DOWN}\"”表示。

如果需要发送多个重复的单字母按键,不必重复输入该字母,SendKeys允许使用简化格式进行描述,使用格式为“{按键

数字}”。例如要发送10个字母“x”,则输入“WshShell.SendKeys \"{x 10}\"”即可。 例一:WshShell.SendKeys \"^{ESC}u\"

页脚内容91

2018年普通高等学校招生全国1卷

代码的含义为:按下Ctrl+Esc组合键(相当于按Win键)打开“开始”菜单,接着按U键打开“关机”菜单。

例二:让VBS脚本自动在记事本中输入一行文字“hello, welcome to cfan”。 Dim WshShell

Set WshShell=WScript.CreateObject(\"WScript.Shell\") WshShell.Run \"notepad\" WScript.Sleep 2000

//本行的含义为是脚本暂停2秒,给notepad一个打开的时间,有时时间太短可能导致后面的字符无法进入编辑区

WshShell.AppActivate \"无标题 -记事本

\"//AppActivate为寻找可执行程序的标题框,”无标题-记事本”内容你的自己打开看一下

WshShell.SendKeys \"hello, welcome to cfan\" 作业1:让脚本自动输入下面两段小短句 This is the most wonderful day of my life because I'm here with you now

作业2:让脚本在输入短句后自动关闭记事本,并保存文件名为“test”,注意关闭记事本可以直接使用组合按键Alt+F4来实现。

例三:制作能自动定时存盘的记事本

我们最常用的记事本没有Word、WPS那样的自动定时存盘功能,其实利用VBS脚本再加上SendKeys命令,就能弥补这个遗憾。打开记事本,输入以下内容(为容易描述和分析,把代码分为四个部分):

'第一部分:定义变量和对象

Dim WshShell, AutoSaveTime, TXTFileName AutoSaveTime=300000

Set WshShell=WScript.CreateObject(\"WScript.Shell\")

TXTFileName=InputBox(\"请输入你要创建的文件名(不能用中文和纯数字):\") '第二部分:打开并激活记事本 WshShell.Run \"notepad\" WScript.Sleep 200

WshShell.AppActivate \"无标题 -记事本\" '第三部分:用输入的文件名存盘 WshShell.SendKeys \"^s\" WScript.Sleep 300

WshShell.SendKeys TXTFileName WScript.Sleep 300

WshShell.SendKeys \"%s\" WScript.Sleep AutoSaveTime '第四部分:自动定时存盘

While WshShell.AppActivate (TXTFileName)=True WshShell.SendKeys \"^s\"

WScript.Sleep AutoSaveTime Wend

WScript.Quit

页脚内容91

2018年普通高等学校招生全国1卷

将其保存为记事本.vbs,以后要使用记事本时,都通过双击这个脚本文件来打开。

程序说明:这个脚本的基本思路是定时向记事本发送Ctrl+S这个存盘组合键。 第一部分:定义了脚本中需要用到的变量和对象。“AutoSaveTime”变量用来设置自动存盘间隔,单位为毫秒,这里设置为5分钟。“TXTFileName”变量通过输入框取得你要创建的文本文件名称。

第二部分:运行记事本,对于Windows本身提供的程序,比如计算器等,可直接在“WshShell.Run”后输入程序名称,如\"calc\",对于非系统程序,则可输入完全路径,但要注意使用8.3格式输入,比如“\"D:\\Progra~1\\Tencent\\QQ.exe\"”。

第三部分:这里用SendKeys命令执行了这样的操作流程(请注意每个操作之间延时命令的使用):在记事本中按Ctrl+S组合键→弹出保存文件的窗口→输入文件名→按Alt+S组合键进行保存(默认保存在“我的文档”目录)。

第四部分:定时存盘的关键,通过“While……Wend”这个当条件为“真”时循环命令,实现自动存盘代码“WshShell.SendKeys

\"^s\"”和定时代码“WScript.Sleep

AutoSaveTime”的重复执行。因为不能让这个定时存盘循环一直执行,退出记事本后,必须自动退出脚本并结束循环,所以设计了一个循环判断条件“WshShell.AppActivate

TXTFileName=True”,当记事本运行中时,可以激活记事本窗口,这个条件运行结果为“True”,定时存盘循环一直执行,退出记事本后,脚本无法激活记事本窗口,就会跳出循环,执行“Wend”后面的“WScript.Quit”退出脚本。

例四:关机菜单立刻显身

打开记事本,输入以下命令,并将其保存为1.vbs: set WshShell = CreateObject(\"WScript.Shell\") WshShell.SendKeys \"^{ESC}u\"

双击运行它,你会发现关机菜单立刻出现了。

将“WshShell.SendKeys \"^{ESC}u\"”改为“WshShell.SendKeys \"^+{ESC}\"”,运行一下看看是否打开了任务管理器。

让我们举个例子利用SendKeys自动上网并登陆博客

将下面的脚本复制到一个文本文件中,并将其文件名命名为:自动登陆.vbs,然后将拨号软件及本脚本一起复制到程序——启动项中,就可以实现自动拨号上网,并登陆到博客上。

代码如下:

Set wshshell=CreateObject(\"wscript.shell\")

wshshell.AppActivate \"连接 MAE-301U拨号连接\" wscript.Sleep 20000

wshshell.SendKeys \"{enter}\" wshshell.Run \"iexplore\" WScript.Sleep 2000

wshshell.AppActivate \"hao123网址之家---实用网址,搜索大全,尽在www.hao123.com - Microsoft

Internet Explorer\" '引号中的内容修改为你的浏览器打开后标题栏中的内容 wshshell.SendKeys \"%d\"

wshshell.SendKeys \"http://passport.baidu.com/?login\"

页脚内容91

2018年普通高等学校招生全国1卷

wshshell.SendKeys \"{enter}\" WScript.Sleep 2000

wshshell.SendKeys \"此处修改为博客帐号\" wshshell.SendKeys \"{tab}\"

wshshell.SendKeys \"此处修改为博客密码\" wshshell.SendKeys \"{enter}\" wshshell.SendKeys \"%d\"

◎VBS中Sendkey键盘对应的码表

Key Code

------------------------------ Shift + Ctrl ^ Alt %

BACKSPACE {BACKSPACE}, {BS}, or {BKSP} BREAK {BREAK}

CAPS LOCK {CAPSLOCK}

DEL or DELETE {DELETE} or {DEL} DOWN ARROW {DOWN} END {END}

ENTER {ENTER}or ~ ESC {ESC} HELP {HELP} HOME {HOME}

INS or INSERT {INSERT} or {INS} LEFT ARROW {LEFT} NUM LOCK {NUMLOCK} PAGE DOWN {PGDN} PAGE UP {PGUP}

PRINT SCREEN {PRTSC} RIGHT ARROW {RIGHT} SCROLL LOCK {SCROLLLOCK} TAB {TAB}

UP ARROW {UP} F1 {F1} F2 {F2} F3 {F3} F4 {F4} F5 {F5} F6 {F6} F7 {F7} F8 {F8}

页脚内容91

2018年普通高等学校招生全国1卷

F9 {F9} F10 {F10} F11 {F11} F12 {F12} F13 {F13} F14 {F14} F15 {F15} F16 {F16}

第十节 ◎Vbs脚本编程简明教程之十 —— Vbs脚本编程常用的编辑器

Vbs脚本常用的编辑器当然是notapad,不过这个编辑器的功能当然实在是太弱了一点,其实有很多的专用的脚本编辑器可以大大方便vbs脚本的编写。我常用的有两种:

1、VBSEDit汉化版

2、primalscript汉化版,可以对30多种脚本进行编辑

第十一节 ◎Vbs脚本编程简明教程之十一 ——FSO中文件的基本操作

一、文件属性:

在windows中,文件的属性一般用数字来表示:

0代表normal,即普通文件未设置任何属性。 1代表只读文件。 2代表隐藏文件。 4代表系统文件。 16代表文件夹或目录。 32代表存档文件。 1024代表链接或快捷方式。例如: set fs=wscript.createobject(“scripting.filesystemobject”) set f=fs.getfile(“d:\\index.txt”)

msgbox f.Attributes ‘attributes函数的作用是显示文件属性

需要说明的是:msgbox显示的结果往往不是上面说明的数字,而是有关属性代表数字的和。

二、创建文件:object.createtextfile方法,注意创建前一般需要检查文件是否存在。

例如:set fso=wscript.createobject(“scripting.filesystemobject”) if fso.fileexists(“c:\\kk.txt”) then msgbox “文件已存在” else

set f=fso.createtextfile(“c:\\kk.txt”) end if

如需要强制覆盖已存在的文件,则在文件名后加true参数。

三、复制、移动、删除文件:使用copyfile方法、movefile方法、deletefile

页脚内容91

2018年普通高等学校招生全国1卷

方法。例如:

set fso=wscript.createobject(“scripting.filesystemobject”)

fso.copyfile “c:\\kk.txt”,”d:\\1\\kk.txt”,true //如上文说述,true代表强制覆盖 fso.movefile “c:\\kk.txt”, “d:\\” //移动文件 fso.deletefile “c:\\kk.txt” //删除文件 四、文件的读写:

1、打开文件:使用opentextfile方法

如:set ts=fso.opentextfile(“c:\\kk.txt”,1,true)

说明:第二个参数为访问模式1为只读、2写入、8为追加 第三个参数指定如文件不存在则创建。

2、读取文件:read(x)读x个字符;readline读一行;readall全部读取 如:set ffile=fso.opentextfile(“c:\\kk.txt”,1,true) value=ffile.read(20) line=ffile.readline contents=ffile.readall 3、常见的指针变量:

atendofstream属性:当处于文件结尾的时候这个属性返回true。一般用循环检测是否到达文件末尾。例如:

do while ffile.atendofstream<>true ffile.read(10) loop

atendofline属性:如果已经到了行末尾,这个属性返回true。 Column属性(当前字符位置的列号)和line属性(文件当前行号):在打开一个文件后,行和列指针都被设置为1。

4、在文件中跳行:skip(x) 跳过x个字符;skipline 跳过一行 5、在文件中写入字符:可以用2-写入和8-追加的方式来写入 其方法有:write(x)写入x字符串;writeline(x)写入x代表的一行 writeblanklines(n) 写入n个空行

注意:最后一定要使用close方法关闭文件。读文件后一定要关闭,才能以写的方式打开。

第十二节 ◎Vbs脚本编程简明教程之十二—使用系统对话框

在VBS脚本设计中,如果能使用windows提供的系统对话框,可以简化脚本的使用难度,使脚本人性化许多,很少有人使用,但VBS并非不能实现这样的功能,方法当然还是利用COM对象。

1、SAFRCFileDlg.FileSave对象:属性有:FileName — 指定默认文件名;FileType —

指定文件扩展名;OpenFileSaveDlg — 显示文件保存框体方法。

2、SAFRCFileDlg.FileOpen 对象:FileName — 默认文件名属性;OpenFileOpenDlg — 显示打开文件框体方法。

3、UserAccounts.CommonDialog对象:Filter — 扩展名属性(\"vbs File|*.vbs|All Files|*.*\");

页脚内容91

2018年普通高等学校招生全国1卷

FilterIndex — 指定

InitialDir — 指定默认的文件夹 FileName — 指定的文件名 Flags — 对话框的类型 Showopen方法:

很简单,ok,让我们来举两个简单的例子: 例一:保存文件

Set objDialog = CreateObject(\"SAFRCFileDlg.FileSave\") Set objFSO = CreateObject(\"Scripting.FileSystemObject\") objDialog.FileName = \"test\" objDialog.FileType = \".txt\"

intReturn = objDialog.OpenFileSaveDlg If intReturn Then

objFSO.CreateTextFile(objDialog.FileName & objdialog.filetype) Else

Wscript.Quit End If

注意:1、SAFRCFileDlg.FileSave对象仅仅是提供了一个方便用户选择的界面,本身并没有保存文件的功能,保存文件还需要使用FSO对象来完成。2、用FileType属性来指定默认的文件类型。3、在调用OpenFileSaveDlg方法时,最好把返回值保存到一变量中,用它可以判断用户按下的是确定还是取消。

例二:.打开文件

set objFile = CreateObject(\"SAFRCFileDlg.FileOpen\") intRet = objFile.OpenFileOpenDlg if intret then

msgbox “文件打开成功!文件名为:” & objFile.filename else

wscript.quit end if

例三:比较复杂的打开文件对话框

Set objDialog = CreateObject(\"UserAccounts.CommonDialog\") objDialog.Filter = \"vbs File|*.vbs\" objDialog.InitialDir = \"c:\\\" tfile=objDialog.ShowOpen if tfile then

strLoadFile = objDialog.FileName msgbox strLoadFile else

wscript.quit end if

说明:在脚本中加入 objDialog.Flags = &H020 看看会出现什么结果。

◎Vbs脚本编程简明教程之十三—

页脚内容91

2018年普通高等学校招生全国1卷

WMI基础之一

WMI即Windows 管理规范,是用户管理本地和远程计算机的一种模型。通过它可以访问、配置、管理和监视几乎所有的 Windows 资源。WMI的语法十分简单,基本上常见的命名空间、对象等用几乎一模一样。它对应的是Windows里的WMI服务(winmgmt)。

一、WMI的起源

几年前,几家资深的计算机公司由于系统管理领域缺少标准,委托DMTF启动了CIM(通用信息模型)项目,理想的CIM是一种不受限制于任何特定实现环境的管理工具。WMI是CIM的微软实现,它有很多类是从CIM中派生出来的。

二、WMI的命名空间

那么命名空间是做什么作用的呢?我简单这样说,在同一段代码中,如果有两个变量或函数的名字完全相同,就会出现冲突。命名空间就是为解决变量、函数的命名冲突而服务的。解决的办法就是将你的变量定义在一个不同名字的命名空间中。就好像财政局有个张三,公安局也有个张三,但我们清楚,就是因为他们分属不同的单位。有些地方可能不太准确,但大致意思就是这样了。

WMI的命名空间创建了一个层次结构,有点类似于我们的目录文件结构。 1、 root-作为所有其他名字的占位符; 2、 root\\default-与注册表操作有关的类; 3、 root\\security-与系统安全有关的类;

4、 root\\cimv2-从CIM派生的类,代表我们最常用的工作环境。 三、WMI的对象路径

WMI的对象路径用来在CIM库中定位类和它的事例,对象路径用两个反斜杠\\\\开头,第一个元素是目标计算机的名字,第二个元素是相应的WMI命名空间,第三个元素是相应的类名,并用 : 将它与命名空间分隔开来。例如:\\\\..\\root\\cimv2:win32_service

其中那个 . 代表是本地系统。

四、WMI的查询语言——WQL仅仅是ANSI SQL的一个子集,只能用于数据的提取。

数据、事件查询的基本语法为:

Select pro1 , pro2 , pro3 from myclass(myclassevent)

例如:Select name , path from Win32_share 说明:列出所有共享的名称和路径

也可以使用通配符 * ,例如:Select * from Win32_share 关键字Where 用于限定查询的范围。

例如:Select * from Win32_share where name=”Admin” 五、WMI脚本中使用的三个步骤 步骤 1:连接到 WMI 服务

在任何 WMI 脚本中,第一个步骤都是建立一个到目标计算机上的 Windows 管理服务的连接。方法是调用[作者:临汾市外事旅游局薛靖澜,转载请注明出处] VBScript 的 Getobject 函数并将 WMI 脚本库的名字对象的名称(即“winmgmts:”,后跟目标计算机的名称)传递到 Getobject,并返回一个对象的引用,此时,您就可以调用其提供的方法如:InstancesOf,正如方法名所示,InstancesOf

页脚内容91

2018年普通高等学校招生全国1卷

返回由资源的类名标识的托管资源的所有实例。

步骤 2:检索 WMI 托管资源的实例 一般采用WQL来实现。

步骤 3:显示 WMI 托管资源的属性

最后一个步骤是枚举 检索得到集合的内容。一般采用 For each enum in myclass ……

Next 结构来实现。

WMI基础之二—阻止客人运行你不想运行的程序

很多人都有这样的经验,刚刚装好的系统,让人运行了一些你不想他运行的程序,比如说QQ,又是聊天,又是下载表情,不过一会,流氓插件、病毒、木马已经盘踞了你的计算机,常常是忍痛将这个程序卸载,可是不知情的人很自觉的下载安装,使整个系统无法正常运行。

其实用vbs和wmi结合起来,使你的计算机上有相应的程序安装,别人又无法运行起来太容易了,现在给出代码:

On Error Resume Next '忽略所有的错误 Dim bag,pipe,honker,good Do

good=\".\" '定义为本地计算机

set bag=getobject(\"winmgmts:\\\\\"& good &\"\\root\\cimv2\") 'l连接到cimv2命名空间

set pipe=bag.execquery(\"select * from win32_process where name='qq.exe' or name='qqgame.exe' or name='winmine.exe'\") '看,这是我的计算机上不允许运行的程序,qq、qqgame、winmine(扫雷)如果你还有其他的程序不允许运行,很简单,在其中添加 or name='你不允许运行的程序名'

for each i in pipe i.terminate()

msgbox \"发现盗版系统,现已进行功能限制\" & vbcrlf & \"请使用正版软件!\微软提示\" '此行其实可有可无,有这行只是为了免去怀疑

next

wscript.sleep 60000 '每1分钟检测一次 loop

那么如果我自己想运行这些程序该怎么办呢?[作者:临汾市外事旅游局薛靖澜,转载请注明出处]

很简单,Ctrl+Alt+Del三个键齐按,打开windows任务管理器,在进程中结束Wscript.exe和wmiprvse.exe进程的运行就可以了。

◎Vbs脚本编程简明教程补充读物- 一、初窥WMI()转载

页脚内容91

2018年普通高等学校招生全国1卷

今天,我沼泽将给大家介绍个朋友,它就是Microsoft Windows Management Instrumentation (WMI)。中文名字叫Windows管理规范。从Windows 2000开始,WMI(Windows 管理规范)就内置于操作系统中,并且成为了Windows系统管理的重要组成部分。所以大家很容易就能见到它的,因为我们至少也应该是个Windows 2000的使用者了。下面我将详细介绍它的每个细节,让你从不认识它到喜欢上它。

WMI能做什么?

WMI不仅可以获取想要的计算机数据,而且还可以用于远程控制。远程控制计算机可是大家都喜欢的东西。很多远程监视控制类软件通常的做法是:在远程计算机上运行服务端后台程序,在本地计算机上运行一个客户器端控制程序,通过这二个程序的勾结来实现对计算机的远程控制。这种作法的缺点是十分明显的,当服务端程序关了,这种远程监控就无法实现了,因为没有内线了。而WMI实现的远程监视和控制完全不需要另外装什么服务端的东西,系统默认就将WMI服务给开了。具体说来,WMI的本领如下:

1.获取本地和远程计算机的硬件软件信息。

2.监视本地和远程计算机的软件和服务等运行状况。 3.控制本地和远程计算机的软件和服务运行。 4.高级应用。 如何访问WMI?

当我们知道WMI的某些本领后,我们已经很想知道如何认识他并利用他了。利用WMI有许多途径,简单说来有三种了:

1.通过微软给我们提供的各种工具来实现普通查询和操作。主要包括命令提示符下面的WMIC,还有就是微软给我们提供的WMI TOOL,大家可以到微软的网站上免费下载,当然我也可以给大家免费提供。

2.通过自己编写脚本来实现更灵活操作。要想真正灵活实用,对WSH脚本的熟悉是必须的,当然如果你不熟悉也没有关系,稍后我会给大家详细解释的。

3. 通过编写我们自己的程序来访问并操作它。什么语言都行。如果用.NET类程序要简单些了,如果用VC等要复杂些了,起码我是这么认为的。

4.还有个访问它的方法,就是到它的一个巢穴。在C:\\WINDOWS\\system32\\wbem目录中的东西都和它有密切联系,有日志和各种工具,在里面你可以找到很多答案的。不过这些东西一般都不适合我们新手玩了,感觉有点吓人。

我们今天的任务?

今天我们的任务有五个:

任务一:利用WMIC列出远程计算机上的所有进程。 任务二:利用WMIC关闭本地进程。

任务三:通过WMIC把远程主机的进程信息保存在一个网页中 任务四:利用脚本实时监视对方进程 任务五:利用脚本给对方开放共享

查看和监视进程,还要把进程给杀掉,最后还要给对方开个共享,我们这位朋友快把坏事做尽了。明白了我们的任务,我们就可以上路了。这次我们将主要借助 WMIC和脚本来实现我们的任务,所以我们将主要分为两大部分来讲解。在五个任务的实战中我们将更加深入地理解它,没有基础没有关系,我将尽力去解释所有的所谓的基础,让大家能很轻松地和这位朋友交流。

页脚内容91

2018年普通高等学校招生全国1卷

第一部分:利用WMIC来认识WMI

WMIC是Windows Management Instrumentation Commandline的简称,WMIC扩展WMI,提供了从命令行接口和批命令脚本执行系统管理的支持。为WMI名称空间提供了一个强大的、友好的命令行接口。有了WMIC,WMI就显的平易近人了。

执行“WMIC”命令将启动WMIC命令行环境。第一次执行WMIC命令时,Windows首先要安装WMIC,然后显示出WMIC的命令行提示符。在 WMIC命令行提示符上,命令将以交互的方式执行。如果你不知道该如何和它交互,请敲个“/?”,细细看完全部的说明,你就知道了。WMIC也可以按照非交互的模式运行。如果要执行某个单步的任务,或者运行批命令中的一系列WMIC命令,非交互模式就很有用。要使用非交互模式,只要在同一个命令行上启动 WMIC并输入要执行的命令就可以了。

1.任务一:利用WMIC列出远程计算机上的所有进程

这是一个实现起来很简单的任务,和你用一个DOS命令一样简单,因为我们要循序渐进嘛,所以安排了这么一个热身任务。在命令提示符下敲入下面的命令,我们将看到。

WMIC /node:192.168.1.2 /user:net process 解说:

1)上面命令中的NODE和USER是全局开关。如果你不愿意另外输一次密码,你也可以用PASSWORD开关,后面写上密码就可以了(WMIC /node:192.168.1.2 /user:net /password:password process)。千万要注意,这里的用户名和密码都必须是管理员级别的,其它的无效。WMIC提供了大量的全局开关、别名、动词、命令和丰富的命令行帮助增强用户接口。全局开关是用来配置整个WMIC会话的选项。

2)Process是个别名,执行了一个Win32_process类的WQL查询,至于说是WMI的类是什么东西,感兴趣的就自己找资料多多了解,如果你很懒的话,就等我有时间给你开课讲解。别名是用户和WMI名称空间一个简化语法的中间层。当你指定一个别名时,动词(Verb)表示要执行的动作。

3)如果你愿意,你可以在该后面加上个动词等,比如 LIST FULL等(如:WMIC /node:192.168.1.2 /user:net /password:password process),这样你就看得更清楚了。

小提示:安装了WMIC的机器可以连接到任何一台安装了WMI的机器,被连接的机器不需要安装WMIC。

2.任务二:利用WMIC关闭本地进程 执行下面的命令将关闭正在运行的QQ。我比较胆小,所以不敢关别人的QQ,只能拿我的QQ试验了,如果你的智商还够用的话,胆子比较大的话,你很快就会去关别人的了。

WMIC

process where name=”qq.exe” call terminate 解说:

1)这次我们是用交互式的方法来执行任务,具体界面我就不多说了,图上画的比我说的好多了。

2)Call也是个动词,这个动词可是厉害了,控制类的没有不用它的,它就是可以调用各种类的各种方法的大将。这里我们调用了terminate方法。从字面上你就可以看出是恶狠狠的。

页脚内容91

2018年普通高等学校招生全国1卷

3)Where能够让你查询和筛选。在超级多的实例中找到你想要的。实例就是指每个类的具体实现了。前面的例子中看到的各个进程都分别算是WIN32_PROCESS中的一个实例。

3.任务三:通过WMIC把远程主机的进程信息保存在一个网页中

这个任务和任务一中的大致相同,是任务一的加强。在任务一中信息以文本的形式显示出来了。其实除了文本形式的输出之外,WMIC还能够以其他形式返回命令执行结果,例如XML、HTML或者CSV(逗号分隔的文本文件),如图3所示。我们可以敲入下面的命令:

wmic /output:C:\\1.html /node:192.168.1.2 /user:net process list full /format:hform.xsl

输入密码 :****** 解释:

1)全局开关OUTPUT指明将这些信息保存在什么地方。

2)全局开关FORMAT指明了用什么样的格式,至于说有那些格式可以用,你可以参看C:\\WINDOWS\\system32\\wbem目录中的*.xsl文件,你甚至不用管它们从哪里来的,用就是了。挨着看看,一定可以找到你喜欢的。

第二部分:利用脚本来认识WMI

命令提示符的工具确实好用,但是却显示不出我们是高手,高手都是能利用程序来实现目的的。下面我们就开始用脚本来实现我们的任务,功能将更加强大,操作将更加灵活。

无论脚本还是真正意义上的程序,要检索 WMI 托管资源信息进而查询并利用WMI,都需要遵循以下三个步骤的。

1.连接到 WMI 服务。建立一个到目标计算机上的 Windows 管理服务的连接。

2.检索 WMI 托管资源的实例。主要取决于要执行的任务。 3.显示WMI 某实例属性和调用其方法。 1.任务四:利用脚本实时监视对方进程

在任务一和任务三中我们都是在查看对方的进程,出来的结果对我们意义不是很大,在这个任务中我们要从现在开始每当他开一个任务我们就察觉到,并把它记录下来。我们要在他开进程的那一秒开始报告并记录,我们要清楚他所开的程序所在的位置,我们要比他更清楚地知道这些信息。

现在我们就按照前面提到的三个步骤来实现任务。

首先,我们连接到对方的WMI。在这里我们首先调用 VBScript 的中的Createobject()来得到一个对象,然后利用这个特殊的对象的方法来连接到远程的计算机上。这个特殊的对象就是wbemscripting.swbemlocator。

set olct=createobject(\"wbemscripting.swbemlocator\")

set wbemServices=olct.connectserver(strComputer,\"root\\cimv2\ 注意其中的strComputer就是你所要连接的计算机的名称或者IP地址,strUser,strPwd当然就是用户名和密码了,我们说过这个用户必须是具有管理员权限的才可以。root\\cimv2是WMI的命名空间,关于WMI的命名空间,大家可以到“计算机管理\\WMI控件”中看到,这里面的学问就大了,得慢慢琢磨,为了我们的任务快速实现,我就不多解释了。用这种方法连接到WMI,返回一个对SWbemServices对象的引用,一旦有一个对 SWbemServices对象的引用。我们就可以进行第二个步骤了。

页脚内容91

2018年普通高等学校招生全国1卷

在第二个步骤中,我们将得到WMI 托管资源的实例,我们利用WbemServices中的一个方法ExecNotificationQuery可以查询我们所要的类,进而可以得到该类中实例。

Set colMonitoredProcesses = wbemServices. _

ExecNotificationQuery(\"select * from __instancecreationevent \" _ & \" within 1 where TargetInstance isa 'Win32_Process'\")

注意这里有个类似于SQL语言的查询语言,这里叫做WQL语言,懂SQL的一看就明白了,不懂的就在网上找找它的资料,满天都是。得到的colMonitoredProcesses是所查询的类的实例的集合。有了这些我们的第三个步骤就可以开始了。

在第三个步骤中,我们将显示出得到的实例中的属性。刚才我们得到的是实例的集合,在这里我们通过 colMonitoredProcesses.NextEvent来获取每一个具体的实例,得到每一个具体的实例后,我们就可以显示出他们的属性,也就是我们想看的东西了。这里我们显示了CommandLine的属性值。

到现在你是否有些迷惑了,因为你还不知道到底WMI里面有那些类,具体类又有哪些属性,呵呵,没有关系的,用一些工具可以很轻松的得到这些信息。比如系统自带的wbemtest,在运行中敲入这个程序名,你就可以看到这些了,它也遵循连接、查询、枚举这三个步骤。自己慢慢玩吧,很快你就会发现WMI太大了,单是命名空间就有10多个,然后单是我们常用的空间root\\CIMV2里面就有近1000个类,每个类里面又有好多的属性,有些类还有好多方法。哈哈,头晕了吧?没关系,其实你只需要知道其中的一些就好了。

看到这些估计你的头已经很大了,但是恭喜你,我们的这个任务已经完成了,是的,就是这么简单,下面我将完整代码奉献出来。

Set colArgs = WScript.Arguments If WScript.arguments.count < 3 then

WScript.Echo \"USAGE:\" & vbCrLf & \" Monitor Computer User Password files\" WScript.quit End If

strComputer = wscript.arguments(0) strUser = wscript.arguments(1) strPwd = wscript.arguments(2) strFile = wscript.arguments(3)

set olct=createobject(\"wbemscripting.swbemlocator\")

set wbemServices=olct.connectserver(strComputer,\"root\\cimv2\ Set colMonitoredProcesses = wbemServices. _

ExecNotificationQuery(\"select * from __instancecreationevent \" _ & \" within 1 where TargetInstance isa 'Win32_Process'\") i = 0

Do While i = 0

Set objLatestProcess = colMonitoredProcesses.NextEvent

Wscript.Echo now & \" \" & objLatestProcess.TargetInstance.CommandLine Set objFS = CreateObject(\"Scripting.FileSystemObject\") Set objNewFile = objFS.OpenTextFile(strFile,8,true) objNewFile.WriteLine Now() & \" \" &

页脚内容91

2018年普通高等学校招生全国1卷

objLatestProcess.TargetInstance.CommandLine

objNewFile.Close Loop

到这个程序的核心了吧?相信你已经懂了其中的很多,剩余的部分代码我稍后解释。我们先来感性认识一下,先看它该怎么用吧!把上面的代码拷贝到记事本中,然后保存为monitor.vbs的文件,然后在命令提示符下输入:

CSCRIPT monitor.vbs

回车,你就会看到帮助,下面举例说明这个脚本的具体用法: CSCRIPT monitor.vbs 192.168.1.2 user password C:\\1.txt 在命令提示符下敲入上面的命令就OK了,每当对方开一个程序的时候,你就可以看到时间,程序路径和程序名。如果你没有时间去看这些信息,你还可以等有时间的时候到C:\\1.txt看到这些信息。

小知识:

每次使用脚本,都必须敲入CSCRIPT和脚本的后缀名,很麻烦。这是因为系统默认的执行引擎是WSCRIPT,可以将它改成CSCRIPT。另外一个让人不爽的是脚本执行后总要显示微软的说明,好像脚本不是我们写的一样。不过你可以通过在命令提示符下敲入下面的命令来解决这个问题:

cscript //nologo //h:cscript //s

这样你以后再运行这些脚本的时候就不用在敲入CSCRIPT了,也不用在写入.vbs的后缀名了,就上面的例子来说,你可以这样用:

monitor 192.168.1.2 user password C:\\1.txt 解释:

1)前面的那几行,大概就是为了显示帮助和处理我们在后面输入的参数。应用到了WScript.Arguments这个对象,利用它我们可以来获取并处理脚本的参数。

2)那个死循环是为了让我们一直监视他(她),每当他开一个程序,我们就得到一个新的实例,我们就可以知道他更多的信息,哈哈,够狠吧。这样你也就知道了,当我们这个脚本运行后,只有通过我们人为中止才能中断监视,人为中止的方法大家可以用CTRL+C来完成,也可以用各种野蛮的方法来中止。

3)在代码中出现的另外一个核心对象就是FileSystemObject,应该是大家的老朋友了吧,我这里就不再做解释了,我们在这里应用它主要是为了将结果同时保存到一个文件中,我们利用它来创建或打开一个文件,将信息追加进去。

4)至于那个NOW,虽然体积很小,但是却正是它给我们提供了时间这个重要的信息。

5)如果你想要监视的是自己的计算机而不是远程的计算机(据我所知,这个应用还是很广的)。那么请将计算机名的参数写为一个小点,用户名和密码留为空。如下所示:

monitor . \"\" \"\" C:\\1.txt

2.任务五:利用脚本给对方开放共享

有了任务四的基础,这次我们就先看代码吧: Set colArgs = WScript.Arguments If WScript.arguments.count < 5 then

WScript.Echo \"USAGE:\" & vbCrLf & \" Rshare Computer User Password SharePath ShareName\"

WScript.quit

页脚内容91

2018年普通高等学校招生全国1卷

End If

strComputer = wscript.arguments(0) strUser = wscript.arguments(1) strPwd = wscript.arguments(2) strPath = wscript.arguments(3)

strShareName = wscript.arguments(4) intMaximumAllowed = 1

strDescription = \"Temporary share\" Const SHARED_FOLDER = 0

set olct=createobject(\"wbemscripting.swbemlocator\")

set wbemServices=olct.connectserver(strComputer,\"root\\cimv2\ Set objSWbemObject = wbemServices.Get(\"Win32_Share\") intReturnValue = objSWbemObject.Create(strPath, _ strShareName, _ SHARED_FOLDER, _ intMaximumAllowed, _ strDescription)

if(intReturnValue = 0) Then

WScript.Echo \"The share have been created successfully\" End If 解说:

1)我们可以看出来前面的那几行是为显示帮助和处理输入参数而存在的。 2)紧接着设置了几个变量,为以后做参数用的。这里我们可以先不理会它。 3)连接到主机的WMI,然后就是查询。前面已经说的很详细了。

4)这次得到实例集后,我们用了它的一个方法,也就是这个方法让共享成为了可能,联系到第二部分的内容,我们不难知道第一个参数表示要共享的路径和文件名,第二个参数表示共享名,第三个参数为0就可以了,第四个参数是指可以连接的人数,第五个参数是共享描述了,而我们只关心前面的两个参数。如果手头有 MSDN那就好办了,到MSDN中可以查到该方法的更详细的内容。

5)这次我们根据第四步的返回值来得到共享是否成功,并给出提示。不同的返回值代表不同的意义。这个信息在MSDN中可以很清楚地查到。比如0代表成功返回,2代表拒绝访问,9代表用户名错误,25代表主机名没有找到等等。

6)这次我们要注意的是,用这个脚本来实现远程文件共享,要求远程存在这个文件,否则无法共享。当然你也可以利用教本创建自己的文件夹,很容易的,自己创建吧。

7)如上脚本创建后的共享是完全共享。就是可以删除修改文件的。 8)用法举例:share netp net swswsw C:\\dodo marsh

好了,到现在为止,大家应该对这位朋友有些了解了,我的介绍任务也就告一段落了,如果大家想进一步认识它,那就主要靠大家的主动性了。这次我们主要通过WMIC和脚本来认识它,下次我将带领大家通过真正的程序代码来认识它,让它也有个象Windows一样漂亮的脸蛋。今天我所提到的估计只能算是WMI的万分之一,都算不上是冰山一角。剩余的要靠自己来发挥了。如果你肯利用你的所学,那么奇迹就会产生。

页脚内容91

2018年普通高等学校招生全国1卷

二、◎WMI轻松入门之一——基本概念

其实我给文章起这样的名字,绝对没有轻视WMI的意思,事实上就连微软也有“WMI非常难于学习而且更难于使用”的说法,在近日的学习过程中更感觉到了WMI检索功能的强大,之所以起个“轻松入门”的名字,我只是有感于外国人写教程在思路上和国人不太一致,西方式的幽默看起来困难无比,再加上一上手就在类的基本结构上展开讨论,吓跑了无数Vbs的爱好者,想从国人常见的角度出发来说说怎么学习WMI而已。百度空间的长度限制太讨厌了,一次发不完,只好分割成三部分,题目只能大致起了,见谅。作者:临汾市外事旅游局薛靖澜,转载请注明

一、什么是WMI?微软有很多说法,大家可以到脚本中心查阅,我这样理解,WMI是一个用于管理Windows系统资源的对象,其内部应是一个树状的数据库,数据库中包含了很多个分支,每个分支被称作命名空间,每个命名空间包含了很多个对托管资源的抽象定义,这种定义叫做类。在很多计算机教材中喜欢把类比作建筑蓝图,依据蓝图建造的楼宇叫做类的实例,我更喜欢将类和其实例的关系比作表格,类就是表格的字段定义,而表中的数据就是一个个的类的实例,也许我这样说会让很多朋友更加糊涂,但是依此类推,WMI中最终存在的是各种软硬件资源的抽象定义,我们利用WMI,就是要按图索骥,通过类定义,获得类实例,检索出符合要求的属性,调用其内置的方法,实现我们的目标。相信很多朋友已经发现,我将WMI等同于CIM库了,我清楚他们不是一回事,但我相信这样更容易理解。如图:

二、WMI的基本结构

严格说来,WMI由四部分组成:

1、 公共信息模型对象管理器——CIMOM 2、 公共信息模型——CIM 3、 WMI提供程序 4、 WMI脚本对象库

其中其第1、2、3三个部分,在使用中很少加以区别,我们一般统称为CIM库。作者:临汾市外事旅游局薛靖澜,转载请注明

所以我们可以认为WMI实际是由两部分组成:CIM库和WMI脚本对象库。在具体使用过程中,我们是通过WMI脚本对象库去访问CIM库,管理托管的资源。也就是说,在我们编写脚本的过程大致可以分为这么几步:作者:临汾市外事旅游局薛靖澜,转载请注明

1、 创建WMI对象脚本库的指针实例;

2、 调用其实例的方法,连接到CIM库,并指明需要访问的资源的逻辑位置;

3、 获得托管资源也就是类的实例的集合; 4、 枚举实例,完成工作。

这几个步骤在我们将来编写的代码中可以明确的反映出来。 三、常用的命名空间

命名空间是个很复杂的概念,相信在微软的网站上一定有很多的篇幅介绍这个概念,据我个人理解,命名空间是对类所处逻辑位置的一个约定。打个比方说:张家也有个孩子叫小强,李家也有个孩子小强。大家站在一起,你大声叫\"小强\你说

页脚内容91

2018年普通高等学校招生全国1卷

这到底是叫哪一个小强呢?张家,李家都是一个姓,一个人的姓实际上就是现实中的一种名字空间。好了,现在你大声叫“张小强”,我们就明确的知道你到底是叫哪一个小强了。这就好比在变量名前加上名字空间前缀。所以可以通俗的说,名字空间就是一个变量的姓氏。问题是这样我们还会碰到一个问题,世界上有很多姓张的,也有可能有很多的张小强,这怎么办呢?这时候我们可以这样说\"张老三家的小强\张是一个名字空间,张老三又是张下面的二级名字空间.

张.老三的家.小强 = 110 张.三丰的家.小强= 119

也许说的更糊涂,但大致就这样吧,我本来也就不是说明这个的。

据微软称,WMI的命名空间共有16个,不过不用担心,我们常用的只有两个:作者:临汾市外事旅游局薛靖澜,转载请注明

1、 root\\cimv2 在这个命名空间里包括了绝大多数与计算机、操作系统相关联的类。

2、 root\\default 管理注册表的类

在使用中,我们用一个字符串表示命名空间,就像文件路径一样。

三、◎WMI轻松入门之二——连接到指定的CIM命名空间

四、常用的脚本对象库

WMI脚本对象库由24个对象组成,在脚本中心有一副脚本库对象模型的图,有兴趣的朋友可以参考一下,作为入门,我们一般只用到其中的四个对象,其继承和层级关系如下:

SwbemLocator教本库对象→SwbemServicesWMI服务对象→SwbemObjectSet类实例集合对象→SwbemObject类的实例

好了,现在让我们来举个例子,详细说明一下这四个对象在脚本中的应用方法:作者:临汾市外事旅游局薛靖澜,转载请注明

例一:用来检索计算机上安装的光驱: strComputer = \".\"

Set objSWbemLocator = CreateObject(\"WbemScripting.SWbemLocator\") Set objSWbemServices = objSWbemLocator.ConnectServer Set colItems = objSWbemServices.ExecQuery(\"Select * from Win32_CDROMDrive\")

For Each objItem in colItems

WScript.Echo \"光盘驱动器的类型: \" & objItem.Caption WScript.Echo \"盘符是: \" & objItem.Id Next

例二:用来检索CPU型号 strComputer = \".\"

Set objSWbemLocator = CreateObject(\"WbemScripting.SWbemLocator\") Set objSWbemServices = objSWbemLocator.ConnectServer

Set objSWbemObjectSet = objSWbemServices.InstancesOf(\"Win32_Processor\") For Each objSWbemObject In objSWbemObjectSet

Wscript.echo \"CPU的型号为:\" & objSWbemObject.name

页脚内容91

2018年普通高等学校招生全国1卷

Next

请注意,这两个脚本虽然简单,却代表了WMI脚本设计中最普遍的东西,可以说是很典型的脚本。让我们来仔细观察一下这两个脚本,讨论讨论一下脚本访问WMI的基本方法:我们可以看到整个脚本的执行过程基本相同:

①定义了SwbemLocator的实例;SwbemServices、SwbemObjectSet、SwbemObject对象;创建了SwbemLocator的实例;②通过SwbemLocator的ConnectServer方法连接到WMI,获得SwbemServices的实例集合;③枚举集合中的每个实例;④显示各实例的一些属性。

让我们来详细说明一下各行代码的详细含义,并请仔细回想我们第二部分WMI基本结构中谈到的编写WMI脚本的基本步骤:(注意:考虑到脚本的简易,我们编写的脚本一般只在本地计算机进行检索,我们只介绍涉及本地的这一部分,涉及到访问远程计算机的部分我们就省略了,其实随着计算机安全技术的发展,仅凭WMI访问远程计算机的可行性是越来越小了)作者:临汾市外事旅游局薛靖澜,转载请注明

1、连接到指定的CIM命名空间

要用WMI对象编程,必须首先创建WMI对象脚本库的实例,连接到目标计算机的CIM命名空间。

方法一:

步骤一、建立SwbemLocator对象的实例。代码为:

Set objSWbemLocator = CreateObject(\"WbemScripting.SWbemLocator\")

然后用SwbemLocator对象的ConnectServer方法(SwbemLocator对象只有1个只读属性Security_和1个方法ConnectServer)建立WMI服务的连接,返回一个命名空间的连接(SwbemServices对象),代码为:

Set objSWbemServices = objSWbemLocator.ConnectServer()

ConnectServer方法共有8个参数,所有参数都是可选的,其参数格式如下: ConnectServer([strComputName],[strNamespace],[strUser],[strPassword],[strLocale],[strAuthority],[iSecurityFlags],[objwbemNamedValueSet])

考虑到WMI的复杂性,在使用中我们如果只是在本地计算机上进行检索和查询,那么我们只需要设置第1、2个参数,其它参数都可以省略;如果想连接到远程计算机,一般需要对前4个参数进行设置,我们也只对此做个简单的介绍。

strServer——计算机名,缺省为本机,本机也可以用”.”

strNamespace——需要登录的CIM命名空间,例如:\"root\\CIMV2\",缺省为\"root\\CIMV2\"。

方法二:用moniker名字法建立WMI服务的连接,这也是微软推荐的连接方法作者:临汾市外事旅游局薛靖澜,转载请注明

moniker名字法是利用GetObject函数直接建立WMI服务的连接,它的要点就是通过编写一个moniker字符串作为GetObject函数的参数,然后返回一个SwbemServices对象。

关于moniker字符串的完整格式如下:

\"winmgmts:[{SecuritySettings}!][\\\\ComputerName][\\Namespace][:ClassName][.KeyProperty='Value']\"

\"winmgmts:\"是前缀, 表示为WMI服务,必须使用;第二部分用来验证权限和假冒级别的,省略。第三部分为计算机名字:\"\\\\.\\\"是计算机名字,默认可省略,其余同上;第四部分CIM命名空间:缺省的命名空间为\"root\\CIMV2\",默认可省

页脚内容91

2018年普通高等学校招生全国1卷

略。

第五部分为类名。第六部分为属性值。注意:当该moniker字符串不包括最后2项时(即为:\"winmgmts:[\\\\ComputerName][\\Namespace]\"),则GetObject(moniker字符串)返回的是一个命名空间的已验证的连接(SwbemServices对象);当不包括最后1项时,返回的是一个CIM类(SWbemObject对象);当包括最后2项时,返回的是一个类的单独实例(SWbemObject对象)。

四、◎WMI轻松入门之三——获得类的实例

2.获得类的实例

我们有4种方法获得类的实例,其中方法1和方法2是通过SwbemServices对象的InstancesOf方法和ExecQuery方法来获得某个类的多个实例组成的集合对象。方法3和方法4则是返回单独的类的实例,即返回的是一个SWbemObject对象。

1)InstancesOf方法获得类的实例集合 InstancesOf方法的语法参数格式如下: SwbemServices.InstancesOf(strClass) strClass为类名,例如\"Win32_Service\"

回顾例二,就是用语句:Set objSWbemObjectSet = objSWbemServices.InstancesOf(\"Win32_Processor \") 来获得\"Win32 Processor \"类的所有实例集合,然后我们可以用

For Each objSWbemObject In objSWbemObjectSet ……

Next 作者:临汾市外事旅游局薛靖澜,转载请注明

语句获得每一个类的实例SWbemObject对象,然后就可以根据我们的需要,进行相应的操作。

2)ExecQuery方法获得类的实例集合

与InstancesOf方法不一样的是,ExecQuery方法可以通过查询语句,只返回匹配部分实例和属性。ExecQuery方法的语法参数格式如下:

SwbemServices.ExecQuery(strQuery)

strQuery为WMI查询语言(WQL)构造的一个查询语句字符串。 例如:作者:临汾市外事旅游局薛靖澜,转载请注明

Set objSWbemObjectSet = objSWbemServices.ExecQuery(\"select ProcessorId from Win32_Processor where DeviceID='cpu0'\")

3)Get方法获得一个类的实例(SWbemObject对象)

此方法也就不必再用 For Each objSWbemObject In objSWbemObjectSet :……:Next 语句从SWbemObjectSet对象中获得每一个类的实例SWbemObject对象,Get方法的语法参数格式如下:

SwbemServices.Get([strObjectPath][.KeyProperty='Value']) strObjectPath是类的名字 KeyProperty是主键属性名 Value是指定的主键属性值

这里要注意的是如果要获得一个类的实例,则

页脚内容91

2018年普通高等学校招生全国1卷

strObjectPath.KeyProperty='Value'中的任何一项都不能省略,例如:

Set objSWbemServices = GetObject(\"winmgmts:\") Set objSWbemObject = objSWbemServices.Get(\"Win32_Processor.DeviceID='cpu0'\")

Wscript.echo “CPU的型号为”:\" & objSWbemObject.ProcessorId 看,结果一样,脚本却简化了不少。

4)直接用moniker名字法获得一个类的实例

在说明Moniker名字法的时候我们说过,当包括最后2项时,返回的是一个类的单独实例,如:Set objSWbemObject = GetObject(\"winmgmts:Win32_Processor.DeviceID='cpu0'\")

Wscript.echo \"首枚CPU序列号:\" & objSWbemObject.ProcessorId 是不是更加简单?仅仅2条语句就获得了CPU的序列号。 3.读取类的实例属性,调用类的方法

实在是太多了,你可以参照C:/WINDOWS/system32/wbem/cimwin32.mfl文件中,对所有类的属性和方法的描述。也可以用下列代码查询,虽然看起来有点困难,不过看的多了也就明白了。作者:临汾市外事旅游局薛靖澜,转载请注明

strClass=inputbox(\"请输入你要查询的类\") strComputer = \".\"

strNameSpace = \"root\\cimv2\"

Const wbemFlagUseAmendedQualifiers = &h20000

Set objWMIService = GetObject(\"winmgmts:\\\\\" & strComputer & \"\\\" & strNameSpace)

Set objClass = objWMIService.Get(strClass, wbemFlagUseAmendedQualifiers) strMOF = objClass.GetObjectText_ WScript.Echo strMOF

五、◎WMI轻松入门之四——解析类定义

在上一篇文章中我们说过,WMI中用类对托管资源进行抽象定义和和管理,那么,什么是类?

类的定义相信在很多面向对象的计算机教材中都能找到,我的理解是:类,是包含了一组独立功能的模块,这个模块由数据和功能组成,其中数据叫做类的属性,完成功能的部分叫做类的方法。我认为类的优点是:类完全可以由张三进行设计,李四可以拿来直接使用,在使用的时候,李四不需要知道类是如何设计、如何实现的,只要知道:这个类可以实现什么样的功能,这个类包含有什么样的方法和属性就可以了。更加重要的是,类还可以进行继承,就像父亲亡故,儿子继承了父亲所有的财产一样,如果我们发现某个类A已经完成了我们需要的大部分功能,我们再去重新设计一个新类来完成我们所有的功能,未免费时费力,根据类可以继承的特性,我们只要声明一个类继承了类A,然后按照需要添加需要的新的数据元素、扩展现有的功能模块,相信工作会简单很多。我看到很多书里都在说代码重用,我不是程序员,不知道所谓的代码重用具体是如何实现的,但是相信类应该在其中起了很重要的作用。

在微软的教程中,对类从功能和继承关系上进行了详细的说明,我不再赘述,

页脚内容91

2018年普通高等学校招生全国1卷

仅仅做一个摘要:

任何资源如果要求WMI进行托管,至少需要两个文件:提供程序和托管对象格式 (MOF) 文件。提供程序是一个中间件,通过调用托管资源的本地 API 来响应 WMI 请求。

每一个WMI托管的硬件和软件资源均有一个类来定义,反过来说,一个CIM类就是一个WMI托管资源的模板,而且资源的所有实例都使用这个模板。这些模板是由属性、方法和限定符组成的。这些属性、方法和限定符都定义在MOF文件中。方法和属性是我们经常遇到的,那么什么是限定符呢?限定符是关于类、属性或方法类型的附加修饰符,类是静态的、抽象的、还是关联的,属性是只读的还是可写的,方法的返回参数等,都定义在其中,那么我们如何知道某个类有那些限定符呢?如下代码可以帮助我们方便的获得类的属性、方法和限定符的信息。

Code:

strComputer = \".\"

strNameSpace = \"root\\cimv2\"

strClass=inputbox(\"请输入你要查询的类\")

Set objClass = GetObject(\"winmgmts:\\\\\" & strComputer & _ \"\\\" & strNameSpace & \":\" & strClass)

WScript.Echo strClass & \" 的类限定信息如下:\" WScript.Echo \"------------------------------\" i = 1

For Each objClassQualifier In objClass.Qualifiers_

If VarType(objClassQualifier.Value) = (vbVariant + vbArray) Then '常数 VBVariant 只与 VBArray 一起返回,以表明 VarType 函数的参数是一个 Variant 类型的数组。

strQualifier = i & \". \" & objClassQualifier.Name & \" = \" & _ Join(objClassQualifier.Value, \ Else

strQualifier = i & \". \" & objClassQualifier.Name & \" = \" & _ objClassQualifier.Value End If

WScript.Echo strQualifier strQualifier = \"\" i = i + 1 Next

WScript.Echo

WScript.Echo strClass & \" 类的属性和属性限定信息\" WScript.Echo \"-------------------------------------------------\" i = 1 : j = 1

For Each objClassProperty In objClass.Properties_ WScript.Echo i & \". \" & objClassProperty.Name

For Each objPropertyQualifier In objClassProperty.Qualifiers_

If VarType(objPropertyQualifier.Value) = (vbVariant + vbArray) Then strQualifier = i & \".\" & j & \". \" & _

objPropertyQualifier.Name & \" = \" & _

页脚内容91

2018年普通高等学校招生全国1卷

Join(objPropertyQualifier.Value, \ Else

strQualifier = i & \".\" & j & \". \" & _

objPropertyQualifier.Name & \" = \" & _ objPropertyQualifier.Value End If

WScript.Echo strQualifier strQualifier = \"\" j = j + 1 Next

WScript.Echo i = i + 1 : j = 1 Next

WScript.Echo

WScript.Echo strClass & \" 类的方法和方法限定信息\" WScript.Echo \"-------------------------------------------------\" i = 1 : j = 1

For Each objClassMethod In objClass.Methods_ WScript.Echo i & \". \" & objClassMethod.Name

For Each objMethodQualifier In objClassMethod.Qualifiers_

If VarType(objMethodQualifier.Value) = (vbVariant + vbArray) Then strQualifier = i & \".\" & j & \". \" & _ objMethodQualifier.Name & \" = \" & _ Join(objMethodQualifier.Value, \ Else

strQualifier = i & \".\" & j & \". \" & _ objMethodQualifier.Name & \" = \" & _ objMethodQualifier.Value End If

WScript.Echo strQualifier strQualifier = \"\" j = j + 1 Next

WScript.Echo i = i + 1 : j = 1 Next

如果我们执行上述代码来查找win32_service类的限定符,一般情况下可以得到如下信息:

win32_service 的类限定信息如下: ------------------------------ 1. dynamic = True 2. Locale = 1033

3. provider = CIMWin32 4. SupportsUpdate = True

页脚内容91

2018年普通高等学校招生全国1卷

5. UUID = {8502C4D9-5FBB-11D2-AAC1-006008C78BC7} win32_service 类的属性和属性限定信息 ------------------------------------------------------ 1. AcceptPause

1.1. CIMTYPE = boolean 1.3. read = True ……

win32_service 类的方法和方法限定信息 ------------------------------------------------- 1. StartService

1.1. MappingStrings = Win32API|Service Functions|StartService 1.2. Override = StartService 1.3. ValueMap = 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,..

……

返回的信息很多,我省略了其中的绝大部分,只保留了一部分典型的来说明我们应该如何读懂类的限定信息。

返回信息的第一部分表明了对于此类的限定信息:

1. dynamic = True Abstract——抽象类,Dynamic——动态类,Association——关联类,表明win32_service类是动态类。

2. Locale = 1033 代表着区域设置或者叫本地化编码,是一组与用户的语言、国家/地区以及文化传统有关的用户首选信息,确定诸如:键盘布局、字母的排序顺序,以及日期、时间、数字、货币等的格式,一般不用管它。

3. provider = CIMWin32 Provider代表的是类的提供程序,说明win32_service类是由CimWin32.dll提供的。

4. SupportsUpdate = True 指出类是否支持实例的修改。

5. UUID = {8502C4D9-5FBB-11D2-AAC1-006008C78BC7} 代表本地计算机上的全球通用唯一的标识符,我不知道有什么用处。

返回信息的第二部分代表了类的属性限定符 1. AcceptPause

这第一行表明检索到的类的属性名是:AcceptPause

1.1. CIMTYPE = boolean CIMType代表属性的数据类型,说明这个属性是布尔型。

1.3. read = True read代表属性可读,而Write则代表属性的值是否可以修改,如果属性没有定义Write限定符,代表什么意思呢?它代表从该类获得的实例的那个属性是不可以改写的,也就是说不能给这个属性赋值。这其实解决了一个困惑我很久的一个问题,为什么我在对很多类的属性进行了赋值后,用Put_方法对修改进行了提交,可是事实上却什么也没有改变。此外还有Key限定符指出该属性是类的键,用于识别在相同资源集合中的托管资源的唯一实例。

返回信息的第三部分代表了类的方法及方法的限定符。现在我们能用到的还不多,就不介绍了,有兴趣的朋友可以参照:http://msdn2.microsoft.com/en-us/library/aa393650.aspx

需要说明的是,不是在每一个类定义或者属性、方法定义中,这所有的限定符都要出现的,可能只出现了其中的一部分。

页脚内容91

2018年普通高等学校招生全国1卷

当然,我们也可以从system32\\wbem\\cimwin32.mof以及system32/wbem/cimwin32.mfl两个文件中读取整个托管资源的类定义和类描述,以及对每个类的属性、方法和限定符的描述,其中包含的信息很多,也包含了更多的类限定符,阅读起来有一定的难度。将上面的例子的代码和vbsedit中包含的Object Browser联合起来,可以得到我们需要的绝大部分的信息。

第十五节 ◎Vbs脚本编程简明教程之十四 —使用dictionary对象

VBS中存在一个特殊的对象-dictionnary,是一个集合对象。一般情况霞,我把这个特殊的集合想象为数组,可以使用其中内建的函数完成存储和操纵数据等基本任务,无须担心数据是在哪些行列,而是使用唯一的键进行访问或者是一个只能运行在内存中的数据库,并只有两个字段分别是:key和item,在使用中,字段key是索引字段。

set sdict=CreateObject(\"Scripting.Dictionary\") sdict.add \"a\ sdict.add \"b\ sdict.add \"c\ for each key in sdict.keys

msgbox \"键名\" & key & \"是\" & \" = \" & sdict (key) next

sdict.removeall

这个脚本很简单,就是定义了一个 dictionary 对象的实例sdict,并加入了三条数据,然后对每一条数据进行了枚举,最后,将对象的实例清空。

Dictionary 对象的成员概要 属性和说明

CompareMode 设定或返回键的字符串比较模式

Count 只读。返回 Dictionary 里的键/条目对的数量 Item(key) 设定或返回指定的键的条目值 Key(key) 设定键值 方法和说明

Add(key,item) 增加键/条目对到 Dictionary

Exists(key) 如果指定的键存在,返回 True,否则返回 False Items() 返回一个包含 Dictionary 对象中所有条目的数组 Keys() 返回一个包含 Dictionary 对象中所有键的数组 Remove(key) 删除一个指定的键/条目对 RemoveAll() 删除全部键/条目对

第十六节 ◎Vbs脚本编程简明教程之十五—VBS内置函数

Abs 函数:返回数的绝对值。

Array 函数:返回含有数组的变体。

页脚内容91

2018年普通高等学校招生全国1卷

Asc 函数:返回字符串首字母的 ANSI 字符码。 Atn 函数:返回数值的反正切。

CBool 函数:返回已被转换为 Boolean 子类型的变体的表达式。 CByte 函数:返回已被转换为字节子类型的变体的表达式。 CCur 函数:返回已被转换为货币子类型的变体的表达式。 CDate 函数:返回已被转换为日期子类型的变体的表达式。 CDbl 函数:返回已被转换为双精度子类型的变体的表达式。 Chr 函数:返回与指定的 ANSI 字符码相关的字符。

CInt 函数:返回已被转换为整形子类型的变体的表达式。 CLng 函数;返回已被转换为Long子类型的变体的表达式。 Cos 函数:返回角度的余弦。

CreateObject 函数:创建并返回对“自动”对象的引用。

CSng 函数:返回已被转换为单精度子类型的变体的表达式。 CStr 函数:返回已被转换为字符串子类型的变体的表达式。 Date 函数:返回当前系统日期。

DateAdd 函数:返回的日期已经加上了指定的时间间隔。 DateDiff 函数:返回两个日期之间的间隔。 DatePart 函数:返回给定日期的指定部分。

DateSerial 函数:返回指定年月日的日期子类型的变体。 DateValue 函数:返回日期子类型的变体。 Day 函数:返回日期,取值范围为 1 至 31。 Eval 函数:计算表达式并返回结果。

Exp 函数:返回 e (自然对数的底) 的多少次方。

Filter 函数:根据指定的筛选条件,返回含有字符串数组子集的、下限为 0 的数组。

Fix 函数:返回数的整数部分。

FormatCurrency 函数:返回的表达式为货币值格式,其货币符号采用系统控制面板中定义的。

FormatDateTime 函数:返回的表达式为日期和时间格式。 FormatNumber 函数:返回的表达式为数字格式。 FormatPercent 函数:返回的表达式为百分数(乘以 100)格式,后面有 % 符号。

GetObject 函数:返回从文件对“自动”对象的引用。 GetRef 函数:返回对能够绑定到一事件的过程的引用。 Hex 函数:返回一字符串,代表一个数的十六进制值。 Hour 函数:返回表示钟点的数字,取值范围为 0 至 23。

InputBox 函数:在对话框中显式一提示,等待用户输入文本或单击按钮,并返回文本框的内容。

InStr 函数:返回一个字符串在另一个字符串中首次出现的位置。

InStrRev 函数;返回一个字符串在另一个字符串中出现的位置,但是从字符串的尾部算起。

Int 函数:返回数的整数部分。

IsArray 函数:返回 Boolean 值,反映变量是否为数组。

IsDate 函数:返回 Boolean 值,反映表达式能否转换为日期。

页脚内容91

2018年普通高等学校招生全国1卷

IsEmpty 函数:返回 Boolean 值,反映变量是否已被初始化。

IsNull 函数:返回 Boolean 值,反映表达式是否含有无效数据(Null)。 IsNumeric 函数:返回 Boolean 值,反映表达式能否转换为数字。

IsObject 函数:返回 Boolean 值,反映表达式是否引用了有效的“自动”对象。 Join 函数:返回通过连接许多含有数组的子串而创建的字符串。 LBound 函数;返回指定维数数组的最小有效下标。 LCase 函数:返回的字符串已被转换为小写字母。 Left 函数:返回字符串最左边的指定数量的字符。

Len 函数:返回字符串中的字符数或存储变量所需的字节数。 LoadPicture 函数:返回图片对象。只用于 32 位平台。 Log 函数:返回数的自然对数。

LTrim 函数;返回去掉前导空格的字符串。 Mid 函数:从字符串中返回指定数量的字符。

Minute 函数:返回分钟数,取值范围为 0 至 59。

Month 函数:返回表示月份的数,取值范围为 1 至 12。 MonthName 函数:返回表示月份的字符串。

MsgBox 函数:在对话框中显示消息,等待用户单击按钮,并返回表示用户所击按钮的数值。

Now 函数:返回计算机的当前系统日期和时间。 Oct 函数:返回表示该数八进制数值的字符串。 Replace 函数:返回一字符串,其中指定的子串已被另一个子串替换了规定的次数。

RGB 函数:返回代表 RGB 颜色值的数字。

Right 函数:返回字符串最右边的指定数量的字符。 Rnd 函数:返回随机数。

Round 函数:返回指定位数、四舍五入的数。 RTrim 函数:返回去掉尾部空格的字符串副本。

ScriptEngine 函数:返回反映使用中的脚本语言的字符串。

ScriptEngineBuildVersion 函数:返回使用中的脚本引擎的编译版本号。 ScriptEngineMajorVersion 函数:返回使用中的脚本引擎的主版本号。 ScriptEngineMinorVersion 函数:返回使用中的脚本引擎的次版本号。 Second 函数:返回秒数,取值范围为 0 至 59。 Sgn 函数:返回反映数的符号的整数。 Sin 函数:返回角度的正弦值。

Space 函数:返回由指定数量的空格组成的字符串。

Split 函数:返回下限为 0 的、由指定数量的子串组成的一维数组。 Sqr 函数:返回数的平方根。

StrComp 函数:返回反映字符串比较结果的数值。 String 函数:返回指定长度的重复字符串。

StrReverse 函数:返回一字符串,其中字符的顺序与指定的字符串中的顺序相反。

Tan 函数:返回角度的正切值。

Time 函数:返回表示当前系统时间的“日期”子类型的“变体”。 Timer 函数:返回时经子夜 12:00 AM 后的秒数。

页脚内容91

2018年普通高等学校招生全国1卷

TimeSerial 函数:返回含有指定时分秒时间的日期子类型的变体。 TimeValue 函数:返回含有时间的日期子类型的变体。 Trim 函数:返回去掉前导空格或尾部空格的字符串副本。

TypeName 函数:返回一字符串,它提供了关于变量的变体子类型信息。 UBound 函数:返回指定维数数组的最大有效下标。 UCase 函数:返回的字符串已经被转换为大写字母。 VarType 函数:返回标识变体子类型的数值。 Weekday 函数:返回表示星期几的数值。

WeekdayName 函数:返回表示星期几的字符串。 Year 函数:返回表示年份的数值。

第十七节 ◎Vbs脚本编程简明教程之十六——响应事件

什么是事件?在我看来,事件就象我们手机上的闹钟,闹钟一响,我们就要去做某些特定的事情。或者这样说,事件就像警钟,当程序运行时,有特殊的事情发生,就会激发事件,事件本身就是一条消息,如果你编写的脚本要对事件进行处理,就需要一个特殊的过程或者函数来接受和处理事件。那么这个特殊的过程或者函数在程序运行时,就不断的监听,看系统是否传来了相应的事件,一旦接受到事件,脚本对此作出反应。

那么事件是从那里来的呢?是否需要我们在脚本中对事件进行编写呢?一般情况下,事件是某个程序在运行中的特殊状态发出的,我们不需要对事件进行编写,只需要编写处理事件的函数。比如说我们用vbs建立了ie的一个实例,那么当ie的窗口被关闭的时候,就会激发出一个叫做OnQuit的事件。

是不是脚本自然而然就能接受事件并进行处理呢?我们说不是的,在创建对象的时候,我们将使用WSH的createobject命令,例如:

Set objie=Wscript.createobject(“internetexplorer.application”,”event_”) 注意到了吗?多了一个参数,这个参数的作用是什么呢?它叫做事件接收端,当脚本连接的对象包含事件时,如果对象调用的事件是OnBegin,那么WSH将会在脚本中调用一个event_OnBegin的事件处理程序。当然事件接受端并不是固定的,如果对象将其定义为MyObj_的话,那么事件处理程序将是:MyObj_OnBegin。

是否很熟悉?在打造个性化QQ一讲中,曾经出现过Window_OnSize(cx,cy)函数,它其实就是一个事件处理程序。

让我们来举个实际的例子完整的看看事件的处理过程:

Set objie=WScript.CreateObject(\"InternetExplorer.Application\ objie.Visible=True

MsgBox \"请关闭浏览器窗口看看效果!\ Wscript.sleep 6000

MsgBox \"现在已经正常关闭了\" Sub event_onquit()

MsgBox \"您确定要关闭浏览器吗?\ End Sub

这段脚本打开了一个IE窗口,然后要求你关闭IE窗口,当你关闭窗口的时候,自动调用事件响应程序。

页脚内容91

2018年普通高等学校招生全国1卷

第十八节 ◎Vbs脚本编程简明教程之十七——访问ADO数据库

ADO是Microsoft提供和建议使用的新型数据访问接口,它是建立OLEDB之上的一个抽象层。微软公司在操作系统中默认提供了 Access 的 ODBC 驱动程序以及 JET 引擎,

一、对ADO对象的主要操作,一般包括6个方面:

1.连接到数据源。通常使用ADO的Connection对象。一般使用相应的属性打开到数据源的连接,设置游标的位置,设置默认的当前数据库,设置将使用的OLEDBProvider,直接提交SQL脚本等。

2.向数据源提交命令。通常涉及ADO的Command对象。可查询数据库并返回结果在Recordset对象中。

3.执行SELECT查询命令。在提交SQL脚本的任务时,不用创建一个Command对象,就可完成查询。

4.可以通过ADO的Recordset对象对结果进行操作。 5.更新数据到物理存储。

6.提供错误检测。通常涉及ADO的Error对象。 二、ADO中主要对象的功能

Recordset对象,用来封装查询的结果。

Field对象,用来表达一行结果中各子段的类型和值。

Error对象,用来检测和判断在数据库操作中出现的错误,比如连接失败。 在ADO中,许多对象名后多了一个\"s\",比如Error->Errors,Field->Fields等等。添加\"s\"意味着是相应对象的Collection(集合)对象,比如Errors是Error对象的Collection对象。Collection有点像数组(Array),但不同的是,Collection可以以不同类型的数据或对象作为自己的元素,而数组中的各元素通常都是相同类型的。所以,在看到一个对象名最后是\"s\",通常表明这是一个Collection对象,比如Errors中的各元素是由Error对象的实例组成的。

三、具体应用

1、创建mdb数据库

ADOX 是ADO 对象的扩展库。它可用于创建、修改和删除模式对象,如数据库和表格等。

其常用的对象有:Catalog—>创建数据库。Column—>表示表、索引或关键字的列。

Key—>表示数据库表中的关键字。

常用的方法有: Append 将对象添加到 其集合。Delete 删除集合中的对象。 set cat= createobject(\"ADOX.Catalog\")

cat.Create \"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=d:\\shujuku.mdb\" Set tbl=createobject(\"ADOX.Table\") tbl.Name =\"MyTable\"

tbl.Columns.Append \"姓名\ 202 'adInteger tbl.Columns.Append \"性别\ 3 'adInteger

tbl.Columns.Append \"工作单位\ 202 ,50 'adVarWChar cat.Tables.Append tbl

不过你要操纵数据库就连一个数据库也不建,未免懒惰了点,用代码虽然可

页脚内容91

2018年普通高等学校招生全国1卷

以完成,但是我觉得对数据约束完成的比较困难,本代码也就是示范个例子,并不推荐使用此类方法。

2、打开数据库

Provider=″Provider=Microsoft.Jet.OLEDB.4.0 ; Data Source=\" Set Objconn = createobject(\"ADODB.Connection\") Objconn.Open Provider & \"数据库名称\" 3、创建记录集

Set Objrs = CreateObject(\"ADODB.Recordset\") 4、执行SQL查询语句

Sql=\"SQL查询语句\" '例如:Select count(*) from table1 Set objrs = objconn.execute(sql)

一般情况下,我们将绝大多数的操作转化为SQL语句完成。 常用的SQL语句

在学习SQL语句之前,让我们先来对数据库做一个基本的了解。一个数据库中可能包含了很多个基本单位叫做表。表格被分为“行”和“列”。每一行代表表的一个单独组成部分,每一列代表相同性质的一组数据。举例来说,如果我们有一个记载顾客资料的表格,行包括姓、名、地址、城市、国家、生日等。而一列则代表了所有的地址或者国家等。

一、建立数据表,我们前边说过利用ADOX.Catalog建立数据库和数据表的方法,但是用的似乎不是很多,一般情况下,如果我们需要在数据库中动态建立一个表,我们将工作交给SQL语句来做,其基本语法是:

CREATE TABLE [表格名]([列名1] 数据类型 , [列名2] 数据类型,... ) 例如我们要建立一个基本顾客表:

Create table [顾客表]([姓名] text(8), [性别] text(2),[住址] text(30)) 二、插入数据项

insert into [数据表名称] (数据项1,数据项2,...) values (值1,值2,...)

insert into语句用来添加新的数据到数据库中的指定表。通过(数据项1,数据项2,...) values (值1,值2,...)来为新添加的数据赋初值。

三、删除数据项

delete from [数据表名称] where [数据项1] like [值1] and/or [数据项2] like [值2]

...

四、更新数据项

update [数据表名称] set 数据项1=值1,数据项2=值2,... where [数据项1] like [值1] and/or [数据项2] like

[值2] ...

该语句可以修改数据库中指定数据表内的指定数据,如果不是用where限定条件就表示修改该表内所有的数据条目。

五、查询数据项

select [数据内容] from [数据表名称] where [数据项1] like [值1] and/or [数据项2] like [值2] ...

order by [数据项] asc/desc

[数据内容]部分表示所要选取的表格中的数据项,使用*表示选取全部。[数据表名称]表示要从哪一个表格中选取,如果你没有接触过数据库可能很难了解什么

页脚内容91

2018年普通高等学校招生全国1卷

是数据表格,没关系,我将在后面用到它的时候再说明。where表示选取的条件,使用like表示相等,也支持>=这样的判断符号,同时使用多个条件进行选取时中间要使用and进行连接。order

by决定数据的排列顺序,asc表示按照[数据项]中的数据顺序排列,desc表示倒序,默认情况为顺序。select语句中除select和from之外其它均为可选项,如果都不填写表示选取该数据表中的全部数据。例如:下面的语句查询某数据库中表名称为:testtable中姓名为“张三”的nickname字段和email字段。

SELECT nickname,email FROM testtable WHERE name='张三' (一) 选择列表

选择列表(select_list)指出所查询列,它可以是一组列名列表、星号、表达式、变量(包括局部变量和全局变量)等构成。

1、选择所有列

例如,下面语句显示testtable表中所有列的数据: SELECT * FROM testtable 2、选择部分列并指定它们的显示次序查询结果集合中数据的排列顺序与选择列表中所指定的列名排列顺序相同。

例如:SELECT nickname,email FROM testtable 3、更改列标题

在选择列表中,可重新指定列标题。定义格式为:列标题=列名

列名 列标题如果指定的列标题不是标准的标识符格式时,应使用引号定界符,例如,下列语句使用汉字显示列标题:

SELECT 昵称=nickname,电子邮件=email FROM testtable (二) FROM子句指定SELECT语句查询的表。

最多可指定256个表,它们之间用逗号分隔。如果选择列表中存在同名列,这时应使用对象名限定这些列所属的表或视图。例如在usertable和citytable表中同时存在cityid列,在查询两个表中的cityid时应加以限定。

(三) WHERE子句设置查询条件

WHERE子句设置查询条件,过滤掉不需要的数据行。例如下面语句查询年龄大于20的数据:

SELECT * FROM usertable WHERE age>20 WHERE子句可包括各种条件运算符:

比较运算符(大小比较):>、>=、=、<、<=、<>、!>、!<

范围运算符(表达式值是否在指定的范围):BETWEEN…AND… NOT BETWEEN…AND…

列表运算符(判断表达式是否为列表中的指定项):IN (项1,项2……) NOT IN (项1,项2……)

模式匹配符(判断值是否与指定的字符通配格式相符):LIKE、NOT LIKE 空值判断符(判断表达式是否为空):IS NULL、NOT IS NULL 逻辑运算符(用于多条件的逻辑连接):NOT、AND、OR

1、范围运算符例:age BETWEEN 10 AND 30相当于age>=10 AND age<=30 2、列表运算符例:country IN ('Germany','China')

3、模式匹配符例:常用于模糊查找,它判断列值是否与指定的字符串格式相匹配。可用于char、

varchar、text、ntext、datetime和smalldatetime等类型查询。

页脚内容91

2018年普通高等学校招生全国1卷

可使用以下通配字符:

百分号%:可匹配任意类型和长度的字符,如果是中文,请使用两个百分号即%%。

下划线_:匹配单个任意字符,它常用来限制表达式的字符长度。 方括号[]:指定一个字符、字符串或范围,要求所匹配对象为它们中的任一个。 [^]:其取值也[] 相同,但它要求所匹配对象为指定字符以外的任一个字符。 例如:

限制以Publishing结尾,使用LIKE '%Publishing' 限制以A开头:LIKE '[A]%' 限制以A开头外:LIKE '[^A]%'

4、空值判断符例WHERE age IS NULL

5、逻辑运算符:优先级为NOT、AND、OR

最后,让我们用一个简单的例子结束这篇教程:

Objku = InputBox(\"请输入单位数据库的路径\默认位置\ Set Objconn = createobject(\"adodb.connection\")

Objconn.open =\"provider=Microsoft.Jet.OLEDB.4.0;Data Source=\" & Objku

sql = \"CREATE TABLE [单位资料](ID Autoincrement PRIMARY KEY,[姓名] text(8),[性别]

text(2),[科室] text(6),[住址] text(30))\" Objconn.execute(sql)

sql = \"INSERT INTO [单位资料]([姓名],[性别],[科室],[住址]) VALUES('张三','男','行管科','解放路12号')\"

Objconn.execute(sql)

sql = \"INSERT INTO [单位资料]([姓名],[性别],[科室],[住址]) VALUES('李斯','女','市场科','五一路12号')\"

Objconn.execute(sql)

sql = \"DELETE FROM [单位资料] WHERE [姓名] = '张三' \" Objconn.execute(sql)

sql = \"UPDATE [单位资料]\"

sql = \"SELECT COUNT(ID) FROM [单位资料]\"

第二章 VBS脚本参考

◎VBS脚本参考之一——使用连字符

前言

这一章的前半部分介绍了 VB 脚本最基本的概念,并且告诉你它可以完成的工作,尤其是 VBS和其它的如 WMI、ADSI 接合在一起的时候。后半部分主要介绍了VBS对系统管理员更有用的部分。

许多脚本和程序语言在向文本输入的时候并不严格的遵守文本的行。例如,尽管下面这个JS 脚 本写了很多行,但是,JS 把它当做一行来处理。这是因为,在大部分的时候,JS 只有看到中止符的时候才认为使一个行的中止。在这个例子中,中止符就是“;”。在实际中敲入的行是和脚本本身不相关的。

页脚内容91

2018年普通高等学校招生全国1卷

var 作者:临汾市外事旅游局薛靖澜,转载请注明出处] objWMI =new

Enumerator

(GetObject(\"winmgmts:\") .

InstancesOf(\"Win32_process\")) ;

正好相反,同样的一段代码,用 VB 写的时候就会报一个语法错误。 Set objWMI =

(GetObject(\"winmgmts:\") .

InstancesOf(\"Win32_process\"))

这是因为,VBS用回车键来代替特定的中止符。为了中止一个VB脚本,你不需要来敲入一个分号或者其它的特殊的符号,你只需要敲回车键就好了。一般来讲,不用中止符的限制,使VBS 在编写的过程中变的简单,但是也有一点会有些复杂。为了增强程序的可读性,建议每行的最大长度不超过80个字符。那么当你的一行代码中有 100 个字符,怎么办呢?尽管看来好象有个很简单的解决办法,但是你不能用回车键来将一行代码分隔成很多行。例如如下的代码片断会返回一个 VB 运行错误因为它用回车键来分隔脚本

strMessageToDisplay = strUserFirstName, strUserMiddleInitial, strUserLastName, strCurrentStatus

Wscript.Echo strMessageToDisplay

你不能用回车建来换行,因为在 VB 中它认为回车是代表一段代码的中止,在上面的代码中,它认为第一行是脚本的第一部分陈述内容。然后认为第二行是另外一部分陈述内容。这样因为 strCurrentStatus 不是一个VBS的命令,所以就报错了。为了解决这个问题,VB 脚本用下划线来表示下面一行是上面一行的代替。在 VB 的早期修订版本中,在第一行末尾加一个空格和一个下划线来表示第二行是第一行的继续。为更明确的表明这个意思,第二行前面要加四个空格。(这样作是为了可读,你其实不必在继续的行前作特定的标识──就是不用在第二行前加四个空格。) 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

strMessageToDisplay = strUserFirstName, strUserMiddleInitial, strUserLastName, _

strCurrentStatus

Wscript.Echo strMessageToDisplay

当继续的行又引号的时候,它就显的特别复杂。例如,架设你用下划线和空格来分隔一个 WMI脚本:

Set colServiceList = GetObject(\"winmgmts:\").ExecQuery(\"SELECT * FROM _ Win32_Service WHERE State = 'Stopped' AND StartMode = 'Auto' \")

如果你运行这个脚本,它会弹出一个错误,因为继续换行符放在了引号中间了,这样它就认为换行符是字符串的一部分。为了分隔这个陈述:

1:在第一行用引号中止,然后插入空格和下划线

页脚内容91

2018年普通高等学校招生全国1卷

2:用 and(&)符号来开始下一行,这表示第二行是第一行字符串的继续

3:在下一行开始之前加入引号 这些引号表示这些陈述是包涵在上面的一行中的,没有了引号,它就VB就解释 Win32_Service 是 VB 的陈述语句,因为这个语句不是合法的,所以就产生了错误。修正的版本如下:

Set colServiceList = GetObject(\"winmgmts:\").ExecQuery(\"SELECT * FROM \" _ & \"Win32_Service WHERE State = 'Stopped' AND StartMode = 'Auto' \")

用这个办法来换行的时候,在适当的位置插入空格要十分小心。在上面的例子当中,空格是添加在“from”之后和下一行的引号之前,如果空格向作偏出,那么字符串会被错位的解释(你看 如果将 FROM 和 Win32_Service 连在一起)会像如下的错误:

\" SELECT * FROMWin32_Service WHERE State = 'Stopped' AND StartMode = 'Auto'

◎VBS脚本参考之二——定义和使用变量

一:Working with Variables

变量是存储在计算器内存中能够存储数据的名称空间。大多数脚本语言允许你隐式的声明变量,使你不用明确的声明就可以使用变量。例如,你运行下面的脚本时候,不会遇到任何类型的错误,尽管它的第一行将一个值赋给了变量 sngDegreesCelsius。尽管它并没有被声明。

sngDegreesCelsius = 11

sngDegreesFahrenheit = ConvertToFahrenheit(sngDegreesCelsius) Wscript.Echo sngDegreesFahrenheit

Function ConvertToFahrenheit(ByVal sngDegreesCelsius) ConvertToFahrenheit = (sngDegreesCelsius * (9/5)) + 32

End Function 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

隐式的变量声明可以让写脚本变的快而且简单,但是在同时,它可能导致难以发现和解决的问题。

为了说明这一点,以前面的脚本为例,前面的脚本将摄氏的 11 度转换成华氏的 51.8 度。下面一个脚本本来应该作同样的事情,但是它却返回了一个 32 的值……

sngDegreesCelsius = 11

sngDegreesFahrenheit = ConvertToFahrenheit(sngDegreesCelsius) Wscript.Echo sngDegreesFahrenheit

Function ConvertToFahrenheit(ByVal sngDegreesCelsius) ConvertToFahrenheit = (sngDegresCelsius * (9/5)) + 32 End Function

上面一个脚本返回一个错误的值。因为在第六行敲入 sngDegreesCelsius,而在后面却敲入了 sngDegresCelsius,因为这个变量并没有赋值,所以 VB 认为它的值是 0,这样继续算下去,结 果为 0,0 再加上 32 所以返回了错误的答案。 像这样的错误很难被发现,因为语法是正确的,所以并没有错误的信息报出来。你期待得到一个 不是 11 的值,并且你得到了。当你写更加复杂的脚本的时候,这个敲入的错误很难被发现和改正。

页脚内容91

2018年普通高等学校招生全国1卷

Declaring Variables in VBScript

为了避免这样的问题发生,你可以显式的声明你的变量。当显示变量声明被要求的时候,脚本中 所有的变量都必须被显示的声明,否则会再运行的时候报错。

例如,如下的脚本用“Option Explicit ”要求所有的变量被显示的声明,并且所有的变量用一

个 dim 语句。 Option Explicit

Dim sngDegreesCelsius Dim sngDegreesFahrenehit sngDegreesCelsius = 11

sngDegreesFahrenheit = ConvertToFahrenheit(sngDegreesCelsius) Wscript.Echo sngDegreesFahrenheit

Function ConvertToFahrenheit(ByVal sngDegreesCelsius) ConvertToFahrenheit = (sngDegresCelsius * (9/5)) + 32 End Function

当你运行这样一个脚本的时候,脚本的主机遇到一个没有声明的变量,这样,脚本中止执行并且 显示出类似下面的一个错误:

C:\\Scripts\\TempConvert.vbs(10, 5) Microsoft VBScript runtime error: Variable is undefined:

'sngDegresCelsius' 在 VB 中声明变量:

1.用 Option Explicit 语句来强制一个变量的声明。

2.用一个单独的 DIM 语句来声明每一个你要用的变量。虽然你只能用一个单独的 dim 来声明 一个变量,但是在变量的后面,你可以添加一些解释来说明变量的用途,如下所示:

Option Explicit 作者:临汾市外事旅游局薛靖澜,转载请注明出处] Dim intFirstNumber ' First number in our simple equation Dim intSecondNumber ' Second number in our simple equation Dim intTotal ' Sum of intFirstNumber and intSecondNumber Initializing Variables

初始化一个变量就是简单的给一个变量赋予一个初始值。例如,如下的几行代码初始化了两个变

量,将 x 赋予 100,将 Y 赋予 abcde X = 100 Y = \"abcde\"

如果你建立一个变量,但是没有给它初始化,(就是没有赋值给它),那么它的值有一下两种可能:

如果它是一个字符串,那么它的值为空 如果它的值是一个数字,那么它的值是 0.

例如:如下脚本创建了两个变量,X,Y,但是没有赋值给他们: Dim X Dim Y

Wscript.Echo X & Y Wscript.Echo X + Y

页脚内容91

2018年普通高等学校招生全国1卷

在脚本的第三行,这两个变量被认为是字符串,(因为&是用来连接两个字符串的)。当它运行 的时候,它显示入 2.8 所示的信息框。因为两个变量都是空,蔓儿他们的接合也是空。所以结 果就是什么都没有。

在脚本的第四行,这两个变量被认为是数字。数字没有被初始化的时候,他们自动的被赋值为 0。 这样,这个行的脚本代表 0+0 的和。

Using the Equals Sign in VBScript

在 VB 脚本中,等号的含义和算数中是不同的。在算数中,x=2+2 是被认为是,x 等于 2 加 2 但是在 VB 中,同样的表达式,被读作:x 被赋值为 2+2 在上面这个例子中,他们并没有什么不同,任何一种办法来说,x 的值都是 4。但是看下面一个 脚本,它用一个 1 到 10 的循环:

For i = 1 to 10 X = X + 1 Next

这个脚本的第二行在算数里面是不可能的,x 怎么可以等于 x+1 哪?原因就是它并不是一个算 数表达式,而是一个合法的 VB 表达式,这里的 X 是一个变量被赋予新的值,在这里这个表示 式被读作:

X 被赋值为 x 当前的值加上 1

就是说,如果 x 当前的值为 3,当运行这个表达式之后,它的值就为 4 了,就是 3 加上 1 事实上,在 VB 中,等号也可以用在对字符串的赋值当中。例如,如下脚本建立一个 message 变量,赋予了它很多字符串的值: 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

Message = \"This \"

Message = Message & \"is a \"

Message = Message & \"test message.\" Wscript.Echo Message

◎VBS脚本参考之三——定义和使用常量

使用常量

常量的意思是在脚本运行的时候,它的值不能改变。例如,如果你有一个脚本将日元转换成美元,假设当前的汇率是 1:0.0088759,你可以在脚本中写上如下的代码:

curConvertedPrice = curPriceInYen * 0.00888759

尽管这个方法可行,但是它会出现一些问题,原因很多不赘述了,为了防止这样的问题发生,用常量的办法来替代用数直接敲入。如果你改变了这个常量,那么你只是需要在定义常量的一个地方更改它就好了。 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

定义常量

在 VB 脚本中,常量的定义是用一个 const 的表达式后加上常量的名字然后和常量的赋值。当你定义常量的是时候,你必须赋值给它一个数值。你不能给一个常量赋值一个变量,或者是一个程序。例如如下代码,尝试用一个变量 NumberOfDepartments,定义一个常量,会产 生一个 Expected literal constant 的错误

页脚内容91

2018年普通高等学校招生全国1卷

NumberOfDepartments = 20

Const NUMBER_OF_DEPARTMENTS = NumberOfDepartments 而你可以将 20 赋给这个常量。

Const NUMBER_OF_DEPARTMENTS = 20 使用固有常量

在 VB的脚本中有一些固有的常量,用来生成 message box,改变输入格式,或者实现其它一些其它的功能。为了提高程序的可读性,你可能需要用这些常量,而不是它们对应等价的数字。

例如,下面的脚本例子用数字来实现 message box 的显示,然后决定在 message box 中, 哪个按钮被按下了。尽管它可以正常的工作,但是对于不熟悉 VB 脚本的人来说,这个脚本很难懂并且很不好编辑。他们必须知道260的意思是:创见一个带有 yes& no 的 message box, 并且第二个按钮是默认的按钮,数字 7 代表用户敲打 NO 那个按钮。

ConfirmDelete = MsgBox (\"Are you sure you want to delete these files?\\"Delete all files\")

If ConfirmDelete = 7 then Wscript.Quit

End If 作者:临汾市外事旅游局薛靖澜,转载请注明出处] 下面这个修正的脚本用了 VBS的固有常量。(VBYesNo,VBDefaultButton2,和 VBNo)用来代替数字。这些使脚本看起来简单易懂。

ConfirmDelete = MsgBox (\"Are you sure you want to delete these files?\ VbYesNo OR VBDefaultButton2, \"Delete all files\") If ConfirmDelete = VbNo then Wscript.Quit End If

用固有常量同样可以帮助你防止当脚本 Update 的时候使脚本实现中断。脚本的常量基本上不可能发生变化。几乎不可能将 VbYesNo 变成 VbNoYes。但是这些常量对应的值会在脚本下次更新的时候更换。用系统常量的时候也方便和其它出现的语言的脚本合并,例如,在 VB 脚本中,1 用来代表 true。在 visual basic.net,true 也等于 1。用 true 这个固有常量,比用硬编码 1 更加容易实现二者之间的转换。 大部分的时候,你会发现你经常重复的使用到如下两个固有常量:

1、VbCrLf.这个等同于按下回车键。它经常用来更改输出显示的格式。例如,如下代码用来显示一行文字,一个空的行,然后再显示一行文字

Wscript.Echo \"This is the first line of text.\" & VbCrLF & VbCrLF & _ \"This is the second line of text.\" 2、VbTab这个常量等同于按下 TAB 键,例如,如下代码来建立三个空格: 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

Wscript.Echo \" 1\" & VbTab & \" 2\" & VbTab & \" 3\" Wscript.Echo \"A\" & VbTab & \"B\" & VbTab & \"C\" Wscript.Echo \"D\" & VbTab & \"E\" & VbTab & \"F\" 当上面这个脚本运行的时候,它将显示如下: 1 2 3 A B C

页脚内容91

2018年普通高等学校招生全国1卷

D E F

这些固有常量只有在用 VB 写的时候才有用,它没有权力去用类似 WMI,ADSI或者脚本的自动控制的对象。在用 VB 脚本写的时候,你可以不用定义就使用 Vb 当中固有的常量,比如 VbCrlf,VbYesNo,但是,当你用 WMI,ADSI 当中常量的时候,你必须显式的声明这些常量。

例如,在 Script Runtime Drive 对象当中有个固有常量 fixed 用来表示 fixed disk drive,Script Runtime可以用这个 fixed 而不需要显式的声明,不用赋值给它……

因为 VB 脚本没有权力访问这个常量,所以任何试图不去定义就访问这个常量的脚本都会失败或者遇到一个错误。例如,如下的脚本可以运行,但是不能标识任何一个你计算器上的 fixed 硬盘。

Set objFSO = CreateObject(\"Scripting.FileSystemObject\") Set colDiskDrives = objFSO.Drives For Each objDiskDrive in colDiskDrives If objDiskDrive.DriveType = Fixed then Wscript.Echo objDiskDrive.DriveLetter End if Next

这个脚本会执行失败,因为 VB 脚本并不知道 Fixexd 这个系统常量的值是 2,取而代之的是将 这个阿常量认为是一个变量。除非你把这个常量赋值,否则它的值就是 empty.在这个例子中,VB 将寻找 DriveType property 的值等于 0 而不是去寻找等于 2,因为 VB 找不到任何这样属 性的 drives,脚本就没有返回任何的数据…… 为了使这个脚本工作,你必须创建一个你自己的常量,叫作 fixed,并且显式的赋值给它为 2, 如下面的事例:

Const Fixed = 2

Set objFSO = CreateObject(\"Scripting.FileSystemObject\") Set colDiskDrives = objFSO.Drives For Each objDiskDrive in colDiskDrives If objDiskDrive.DriveType = Fixed then Wscript.Echo objDiskDrive.DriveLetter End if Next

◎VBS脚本参考之五——时间和日期

VB 脚本用以下三个功能来标识当前的日期,时间或者全部。 Now – 获得当前的日期和时间 Date – 获得当前的日期 Time –返回当前的时间

如:DateInfo = DateInfo & Now & VbCrLf DateInfo = DateInfo & Date & VbCrLf DateInfo = DateInfo & Time & VbCrLf Wscript.Echo DateInfo

页脚内容91

2018年普通高等学校招生全国1卷

Verifying That a Value Is a Date

在用 dates 工作的时候,确定这个数据是时间还是其他是非常重要的。这个对于 WMI 查询和对数据库进行相关操作的时候十分重要。在这些情况下,如果你使用了非法的日期类型,脚本将会报错。而 IsDate 的功能就是告诉你这个数据是不是一个日期的值。当这个值不是一个日期的时候,他返回一个 false(0),如果是一个日期,就返回一个 true(1),日期的值可以用以下方法标识:用#号来标识时间。这是一种被推荐的办法。因为这样的办法消除了防止 VB 脚本将其它非日期的数据解释成日期的可能。如:

#9/3/2002# ,说明:中文系统格式为#年/月/日#。

当然为了确保日期的格式合法,你也可以打开计算机“区域和语言”选项,然后选择自定义,来进行设置。

下面这个脚本创建一个数组,然后列举里面的数值。这个脚本用 IsDate 来决定是不是为合法的日期,并且回显出来这个合法的日期和一段消息,来表示这个是合法的日期。

DateArray = Array(\"6/1/2002\ \"6\ For Each dtmDate in DateArray If IsDate(dtmDate) = 0 Then

Wscript.Echo dtmDate & \" is not a valid date.\" Else

Wscript.Echo dtmDate & \" is a valid date.\" End If Next

说明:为什么 6/1 也是一个合法的日期?因为在 vb 脚本中使用 IsDate 函数的时候,如果脚本遇到一个似是而非的日期时如6/1 的 month/day 的时候, 他自动的添加当前的年份,而变成了 month/day/year,在上面的这个脚本中,运行的年份是2002 年,所以这个日期就变成了 6/1/2002,这个是一个合法的日期。

Retrieving Specific Portions of a Date and Time Value

大部分的时候,你所感兴趣的只是时间或者日期的一部分。例如,你可能有一个备份的脚本,只有在周日或者不是周末的时候来备份你的数据。这样,你可能每天都获得你的事件日志,在每月的 15,30 号清除日志。

VB 脚本用两种特别的办法来的获得当前的日期和时间的一部分。DatePart 函数可以获得当前日期时间的任何部分。此外VB 脚本还提供了其它诸如:Day ,Month,Year 这样的函数来获得日期或者时间的一部分。DatePart 可以获得当前日期时间的特殊部分,它要求两个参数:

Yyyy-年份,返回当前的时间值的年份 q-季度,返回当前季度。

m-月份,返回当前的月份信息

1 – January 2 – February 3 – March 4 – April

5 – May 6 – June 7 – July 8 – August 9 – September 10 – October 11 – November 12 - December

y-一年中的多少天,返回当前日期的数值。从 1 月 1 号起算到 12 月 31 号为止。如2 月 1 号是这个年的第 32 天。

d-日。返回是这个月的多少天。例如 4 月 17 日,则返回 17 w-周几,返回当前周的周几的信息。

页脚内容91

2018年普通高等学校招生全国1卷

1 – Sunday 2 – Monday 3 – Tuesday 4 - Wednesday 5 – Thursday 6 – Friday 7 Saturday ww-一年中的第多少周,返回当前周的信息,1 月 1 号认为是第一周,12 月 31 号是第 52 周。尽管如此,你仍然可以确定哪周是一年中的第一周。

H-小时。返回一天 24 小时的格式中是第多少个小时。例如,下午 2:00 会返回 14,下午 6:00 会返回 18。在午夜到凌晨一点的时候,返回的值是 0,午夜 12 点返回的也是 0。

n-分钟,返回当前时间的分钟。 s-秒数:返回是当前分钟的秒数。

为了使用DatePart 这个函数,你可以创建一个变量并且赋值给它。例如如下的代码将你计算机上当前的时间的年份赋值给变量 CurrentYear

CurrentYear = DatePart(\"yyyy\

在上面的例子中,用到了如下两个参数:

\"yyyy 表示从特定的日期返回年份,这个参数必须放在引号以内。

Date 用来解析的当前的日期,你也可以把特定的日期用引号括起来(例如”6/1/2002”)或者用一个变量来赋值个一个 DATE,例如如下两行代码返回值为 1997

DateToCheck = #8/15/1977#

CurrentYear = DatePart(\"yyyy\" , DateToCheck)

注意:当将一个日期赋值给一个变量的时候,你可以用#将日期放在中间。这样保证 vb 脚本认为它是日期,而不是数字或者字符串等变量。当然你也可以用 CDate 函数来实现这个功能。下面脚本解析出当前的日期,然后显示出当前日期的分支(组成部分)。

Wscript.Echo Now

Wscript.Echo \"Year: \" & DatePart(\"yyyy\" , Now) Wscript.Echo \"Quarter: \" & DatePart(\"q\

当你给DatePart 函数一个错误时间时,它不会报错,但是不会返回你期待的结果。例如,如下代码想返回1899:

Wscript.Echo DatePart(\"yyyy\ 这行代码返回的是 0

Wscript.Echo DatePart(\"h\/1/2002\")

除了 DatePart 函数以外,还其它函数同样可以更改时间的值。如: Day、Hour、Minute、Month、Second、Weekday、Year等 例如:

CurrentDate = Now

Wscript.Echo \"Year: \" & VbTab & VbTab & Year(CurrentDate

◎VBS脚本参考之四——脚本的数据类型

VBScript的数据类型

VBS是一个有着很少数据类型的脚本语言,其并不限制变量为一种单一的数据类型。VBS不允许你定义一个特定数据类型的变量。实际上,VB 脚本只有一种变量类型,叫作variant,它可以存储任何类型的数据。与其相反,其它程序语言

页脚内容91

2018年普通高等学校招生全国1卷

比如 C++是一个对数据类型要求很严格的,因为你必须事先定义变量能存储的数据类型。如果你试图存储任何数据在一个变量上,它将会报错。如果你已经将一个变量赋予特定的数字数据,那么你再将字母变量赋值给它的时候,它将崩溃。作者:临汾市外事旅游局薛靖澜,转载请注明

Variants 可以使脚本编写变得简单。你可以在没有定义数据类型的时候宣告并使用。但是如果你不了解数据类型的强制过程,那么variants会导致一系列的问题。

脚本语言所说的脚本无类,其实是针对脚本编写的人员来说的,对于脚本内部来讲,脚本还是要依照数据类型来工作。例如下面这个简单的表达式c= a + b 脚本语言必须给 a,b 都赋 值(有一定数据类型的值),也就是说,它必须建立并确定这两个数值是为 integer 还是 string。当这些值被定下来之后,它才可以执行相关的操作。

脚本的数据类型赋值的初始化过程是一种数据类型强制转换的过程。数据类型的强制过程是基于特定的规则的,大部分的时候,VB 脚本可以很顺利的完成这个任务。作者:临汾市外事旅游局薛靖澜,转载请注明

但是,类型转换一样会导致问题的发生,例如下面这个例子: intFirstNumber = InputBox(\"Please enter the first number:\")

intSecondNumber = InputBox(\"Please enter the second number:\") intTotal = intFirstNumber + intSecondNumberi Wscript.Echo intTotal

如果你运行这个脚本,并且先后键入 4,2,那么计算器会回显一个 42 来作为 4+2 的结果,而不是你期待的 6。

这是因为,加法运算对于number和string来说都是合法的。VB 脚本给了 4,2 两个值,但是它不知道数据类型,于是,在没有其它的关于数据类型的相关信息的情况下,VB 脚本就用类型强制的办法将这两个变量转换成了string数据。

与其相反,如果你在下面一小段代码中键入 4,2 它将会返回正确 2,这是因为除法运算只是针对numbers 来作的,所以 VB 就用数据强制正确的将这两个变量转换成了 number 数据。

intFirstNumber = InputBox(\"Please enter the first number:\")

intSecondNumber = InputBox(\"Please enter the second number:\") intTotal = intFirstNumber / intSecondNumber Wscript.Echo intTotal

为了避免类似的数据强制的时候发生问题,你需要显式的声明一个变量,这个过程叫做类型初始化。例如如下的 VB 代码用 VB 脚本的 CInt 来在他们想加之前将输入的变量转换为整数型。

intFirstNumber = CInt(InputBox(\"Please enter the first number:\"))

intSecondNumber = CInt(InputBox(\"Please enter the second number:\"))作者:临汾市外事旅游局薛靖澜,转载请注明

intTotal = intFirstNumber + intSecondNumber Wscript.Echo intTotal

此类常见的函数有:Cbool、Cbyte、Ccur、Cdate、CDbl、Cint、CLng、CSng、CStr等。

了解empty和Null之间的不同,对于你脚本的成功与否,起着关键的作用。Empty 变量是一个没有初始化的变量,录入,你用 dim 语句定义一个 curBonus

页脚内容91

2018年普通高等学校招生全国1卷

的变量,这个变量在没有赋给它特定的值的时候,它就是 empty 的。一个 empty 的变量在数据强制的时候,如果是 number 变量就赋值给它 0,如果是 string 的时候,就赋值给它”” (空)。

与其相反,Null 是一个没有合法的赋值的变量。典型的 null 是从数据库操作中产生的。假如你查询一个数据库,想返回一个当前的分红给一个特定的员工,并且将这个值赋给 curBonus,如 果没有分红被分配(赋值),那么变量 curBonus 就是 Null.注意,curBonus 可以是 0,但是你 不能确定它就是 0。你不能假定它的值是 0,因为,有可能的是它实际上有 5000 美元的分红, 但是这个值还没有被输入到数据库中。这就是为什么 VB脚本要将 empty null 这二者加以区别的原因。 二者的区别在数字运算的时候就更加的明显。例如,在下面的脚本片断中,curBonus 被设置成 empty,然后将它加上 curBaseSalary(50000),那么计算的结果是:50000 + 0 = 50000

curBonus = Empty curBaseSalary = 50000

curTotalCompensation = curBaseSalary + curBonus Wscript.Echo TotalCompensation

在下面的版本中,继续同样的操作,只是将 curBonus 的值设定成 Null,当你再次运行这个脚本的时候,你会发现你不是得到结果 50000,而是 Null.任何时候,Null 这个变量在参与数字运算的时候,它的结果是 null这是因为你并不知道 NULL 的真正的值,你不能将它的值赋予为 0,因为你不知道它的值是否真 的是 0。因为你不知道它的值,也就不知道它计算的结果,这样结果只能是 null.(你可以这样 认为:null 的含义是:我不知道。)

curBonus = Null

curBaseSalary = 50000

curTotalCompensation = curBaseSalary + curBonus Wscript.Echo TotalCompensation

Null 值在和数据库和 ADSI 一起工作的时候就会出现错误。幸运的是,你可以使用 IsNull 的办法来确定这个变量是否为 Null.例如,下面的脚本来检察 curBonus 是否为 null,如果值是 null 的话,那么赋值给它为 0。这样可以使他们在计算中生效。当然你也可以选择来回显一个信息框:No bonus information available for this employee.\"

curBonus = Null作者:临汾市外事旅游局薛靖澜,转载请注明 curBaseSalary = 50000 If IsNull(curBonus) Then CurBonus = 0 End If

curTotalCompensation = curBaseSalary + curBonus Wscript.Echo curTotalCompensation

第三章 VBS脚本运行库手册 ◎VBS脚本运行库手册之一(磁盘操作)

页脚内容91

2018年普通高等学校招生全国1卷

文件系统管理是系统管理的一个关键性任务。WSH 和 VB 脚本在这个领域都没有提供相关的功能。幸运的是,你可以通过 script runtime 库来管理这些关键的系统组件,比如磁盘,文件夹和文件。此外,script runtime 库提供了从 text 文件读写的方法,可以用来创建 dictionary和编译脚本。[作者:临汾市外事旅游局薛靖澜,转载请注明出处]

两种主要的脚本语言,VB 脚本语言和 JS 脚本语言起初的时候都是设计给客户端来编写 IE 的。正是因为如此,这两个脚本语言都有一些局限性。例如VB 脚本和 JS 脚本内部都没有提供访问文件管理的一些任务,比如:复制、移动、删除文件等。这样做的目的是为了保护消费者。大多数的的网站不可能让用户通过网页去删除它们硬盘上的东西。尽管如此,脚本已经从类似的 HTML 的按钮之类的开始迅速的发展了。随着 ASP 的到来,浏览器的编写者要求在 server 上管理文件。而随着 WSH 的到来,系统管理员要求有在 web 浏览器外来管理文件了。 作者:临汾市外事旅游局薛靖澜,转载请注明出处] 为了满足这个要求,微软发布的了 Script Runtime Library。它是一个单独的 DLL 文件,scrrun.dll 文件,用来给脚本的编写者们提供一些文件管理的能力,包括以下内容:作者:临汾市外事旅游局薛靖澜,转载请注明出处]

1、获取文件系统的信息,包括获得磁盘、文件和文件夹上的信息。 2、复制,移动和删除文件及文件夹 3、创建和读写文本文件。

除了这些功能之外,Script Runtime Library 提供了创建字典的能力。也可以用来对脚本进行编译,使脚本成为加密的。 Note:

这章只是讨论 FileSystemObject 和 Dictionary 的部分,对于 Encode 部分不作讨论,Script Runtime Library 也是 windows 2000 的一部分,它在你安装或者升级微软的应用程序的时候也随着升级和安装了:这些应用程序有以下几个:

1、WSH 2、VB 脚本 3、IE 浏览器 4、Microsoft Office 5、FileSystemObject

正如它的名字一样,FSO 设计用来帮助你管理文件系统,FSO 允许你获取重要的文件组件信息,包括硬盘、文件夹、文件;也提供一般的系统管理的任务,比如复制、删除、移动文件和文件夹。此外FSO 允许你读写文本文件。

用 FSO 其实有些用词不当,因为实际上 FSO 包含很多个对象,每个对象被设计成用来完成特定的目的。组成 FSO 的对象列在了下表中:作者:临汾市外事旅游局薛靖澜,转载请注明出处]

Drive 代表系统中磁盘或者磁盘的集合

File 代表系统中的一个文件或者文件的集合 Folder 代表文件系统中的一个文件夹或者多个文件夹 TextStream 代表文本文件中的读取、写入或者提交字符串 ※ 磁盘管理

磁盘管理是系统管理的一个重要的部分。作为一个系统管理员,知道安装在这个计算机上磁盘是十分重要的,当然,知道这个磁盘的属性、磁盘类型、子盘大小、总共和剩余空间也是同等重要的。作为一个脚本的编写者,你有两个主要的选择来管理磁盘:WMI & FSO。一般来讲,WMI 更是管理磁盘的首选项,主要有以下几个原因: 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

1、WMI 能返回一些 FSO 无法返回的属性,比如磁道、扇面等。

2、FSO 不能返回一个目标磁盘。而是返回所有的磁盘,然后进行筛选出你感兴趣的磁盘。而你可以用 WMI 通过磁盘符号来返回特定的磁盘,WMI 可以用来返回远程计算机上磁盘的信息,但是 FSO 不可以,除非它用 wshcontroller对象。

页脚内容91

2018年普通高等学校招生全国1卷

虽然 WMI 或许是获得磁盘信息的最好工具。但是这里至少有两个原因使你必须去熟悉 FSO。 第一:因为有些低端的操作系统无法安装 WMI,所以只能使用 FSO; 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

第二:最重要的一点是因为:脚本的编写者们在想到获取磁盘信息的时候就会用到 FSO,而你作为系统管理员,可能会来看其它人的脚本,这样就需要了解 FSO。注:外国人写的真是拗口,我理解这句话的意思就是说FSO比WMI应用的更广泛一些。 ※ 如何返回磁盘信息

在你管理计算机的磁盘之前,你需要知道你的计算机上实际上有多少磁盘可以使用。FSO 允许你管理安装在计算机上的所有磁盘,包括移动硬盘和网络硬盘(就是只要是有盘符的就可以了)为了返回这个集合,你需要首先创建一个 FSO 实例,然后创建磁盘属性的对象。当这个集合返回后,你可用一个 For Each 的循环来重述这个集合。 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

例如,下面的脚本就是要返回安装在本地计算机上的磁盘集合然后返回它们的盘符: 1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 2 Set colDrives = objFSO.Drives 3 For Each objDrive in colDrives

4 Wscript.Echo \"Drive letter: \" & objDrive.DriveLetter 5 Next

脚本运行库手册之二(磁盘操作)

※如何绑定指定磁盘

如果你事先知道要绑定的磁盘(例如C 盘或一个共享文件夹\\\\accounting\\receivables),你可以用 GetDrive 的方法来直接绑定磁盘。这样你可以不用去筛选就获得特定磁盘的信息。GetDrive 需要一个单独的参数:磁盘符号或者是共享文件夹的 UNC 路径。你可以用如下的几种格式:C C: C:\\ 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

在下面的脚本中首先创建一个 FSO 对象,然后用 GetDrive 的方法来直接绑定C盘,然后回显可用的磁盘空间:

1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 2 Set objDrive = objFSO.GetDrive(\"C:\")

3 Wscript.Echo \"Available space: \" & objDrive.AvailableSpace

注意,这里没有 For Each 循环,你就可以获得磁盘的属性。因为脚本是返回一个单独的磁盘对象,而不是所有对象的集合。因此也就不用筛选了。作者:临汾市外事旅游局薛靖澜,转载请注明出处]

※如何列举磁盘驱动器的属性

磁盘集合的作用总是用来监视和列举的。作为一个系统管理员,你需要知道计算机上的可用磁盘,也需要知道磁盘的序列号、可用空间等信息。在你获得当前磁盘的集合或者单个磁盘的时候,你就可以获得下表列出的所有属性。作者:临汾市外事旅游局薛靖澜,转载请注明出处]

1、AvailableSpace——报告磁盘上可以使用的空间,单位是 bytes。如果想以 kb 为单位返回,除以 1024,如果想以 M 为单位返回,则除以 1.048,576。这个属性返回的是可用的磁盘空间的总数。如果一个磁盘启用了磁盘限额,那么他返回的数字可能比实际的要小。

2、DriveLette——返回特定磁盘的盘符。这个盘符不包含那么冒号。例如软盘返回的是A,而

页脚内容91

2018年普通高等学校招生全国1卷

不是A:

3、DriveType——整数的值代表不同的磁盘类型:1:移动硬盘 2:硬盘 3:网络硬盘作者:临汾市外事旅游局薛靖澜,转载请注明出处] 4:CD-ROM 5:RAM 磁盘

4、FreeSpace——返回磁盘剩余空间的总额。单位是 bytes,如果是返回的单位是 kb,就除以 1024,如果是以 M 为单位,除以 1,048,576。注意:这个和磁盘可用空间不一样,剩余的磁盘空间不会考虑磁盘限额。作者:临汾市外事旅游局薛靖澜,转载请注明出处] 5、FileSystem——返回文件系统的类型(FAT,FAT32,NTFS)

6、IsReady——标识磁盘是否可以访问。这个值来判断软盘和CD-ROM是否为空 7、Path——磁盘路径。对于本地磁盘,返回盘符和脱尾符(就是那个冒号),比如A:对于网络磁盘,就返回它的 UNC 路径。

8、RootFolder——返回磁盘根目录下的文件夹。

9、SerialNumber——磁盘的生产商给磁盘分配的序列号。对于软盘和网络硬盘来说,它们的值是 0。

10、ShareName——分配给网络驱动去的共享名称。

11、TotalSize——报告整个的磁盘空间,单位是 bytes,如果想以 kb 为单位,除以 1024,如果想以 M 为单位返回,则单位为 1,048,576。作者:临汾市外事旅游局薛靖澜,转载请注明出处]

12、VolumeName——分配给磁盘的卷名。

为了列举安装在计算机里的磁盘的属性,创建一个 FSO 实例,然后创建一个 FSO 属性的对象,用 For Each 循环,来重现各个磁盘的配置。对于集合当中的每个磁盘,你可以返回一个或者的属性。如下列脚本列举出安装在计算机上所有磁盘的所有属性。 1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 2 Set colDrives = objFSO.Drives 3 For Each objDrive in colDrives

4 Wscript.Echo \"Available space: \" & objDrive.AvailableSpace 5 Wscript.Echo \"Drive letter: \" & objDrive.DriveLetter 6 Wscript.Echo \"Drive type: \" & objDrive.DriveType 7 Wscript.Echo \"File system: \" & objDrive.FileSystem 8 Wscript.Echo \"Is ready: \" & objDrive.IsReady 9 Wscript.Echo \"Path: \" & objDrive.Path

10 Wscript.Echo \"Root folder: \" & objDrive.RootFolder

11 Wscript.Echo \"Serial number: \" & objDrive.SerialNumber 12 Wscript.Echo \"Share name: \" & objDrive.ShareName 13 Wscript.Echo \"Total size: \" & objDrive.TotalSize

14 Wscript.Echo \"Volume name: \" & objDrive.VolumeName

15 Next 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

上述脚本有个潜在的缺点,就是如果没有软盘或者光驱里面没有光盘,会产生一个 disk not ready 的错误出来。当磁盘没有准备好的时候用 FSO 来访问会有些错误的。虽然 FSO 可以标识那些没有准备好的磁盘,但是你访问它的一些属性的时候会报错出来,比如 AvailableSpace 或 FreeSpace。如果磁盘没有准备好,你只可以访问如下的四个属性:DriveLetter、DriveType、IsReady、ShareName。所有尝试访问其它属性都会报错。

幸运的是,IsReady 属性允许你用脚本来检查一个磁盘是否准备好了。IsReady 返回一个 Boolean 值,如果这个值是true,则磁盘准好了,你可以访问它的所有属性,否则如果这个

页脚内容91

2018年普通高等学校招生全国1卷

值是false,则磁盘没有准备好,只能返回上面的四个属性了。可以对每个磁盘,用 IsReady 属性来保证磁盘是准备好的。如果是就返回磁盘的盘符和剩余空间,如果不是就只返回磁盘的盘符。作者:临汾市外事旅游局薛靖澜,转载请注明出处] 1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 2 Set colDrives = objFSO.Drives 3 For Each objDrive in colDrives 4 If objDrive.IsReady = True Then

5 Wscript.Echo \"Drive letter: \" & objDrive.DriveLetter 6 Wscript.Echo \"Free space: \" & objDrive.FreeSpace 7 Else

8 Wscript.Echo \"Drive letter: \" & objDrive.DriveLetter 9 End If

10 Next 作者:临汾市外事旅游局薛靖澜,转载请注明出处] Note:这个问题不会发生在 WMI 上(如果软盘或者光驱中没有盘,脚本就会失败),WMI 只是认为返回的空间为 Null

◎VBS脚本运行库手册之三(管理文件夹)

※管理文件夹

磁盘的属性比如磁盘的剩余空间,磁盘的总额提供了一个全局的信息给系统管理员。但是,对于系统管理而言,磁盘的信息虽然是必须的,但是还不够。知道文件存储在哪个盘固然重要,但是你也需要知道文件是存储在哪个文件夹下的。此外许多的系统管理任务都是发生在文件夹级别的,比如复制,移动,删除和列举文件夹的内容。

FSO 可以返回一个磁盘上文件夹的全部信息。此外,FSO 提供了一系列的方法来完成诸如:复制、移动、删除文件夹的操作。

※ 如何绑定指定的文件夹 在微软的调用文件中,文件夹是 COM 对象。这就是说在你访问一个单独的文件夹的属性时,你必须去创建一个文件夹的对象reference,这个过程叫做绑定。你可以用FSO和GetObject的方法来绑定到一个文件夹。作者:临汾市外事旅游局薛靖澜,转载请注明出处]

当用 GetFolder 的时候,你必须:路径既可以写成本地路径也可以写成 UNC 路径(例如:\\\\accounting\\receivables)。但是通配符不能出现在路径当中。此外,你不可以创建一个单独的对象 reference 来同时绑定到多个文件夹。例如,如下的脚本代码会产生一个错误: objFSO.GetFolder(\"C:\\FSO\

如果你想针对多个文件夹同时工作,你要么用 WMI 或者用针对每个文件夹创建单独的对象reference。

在设置的时候 Set 这个关键词是必须的,因为你要标识这个对象 reference 变量。 作者:临汾市外事旅游局薛靖澜,转载请注明出处] 例如下面的脚本绑定文件夹 C:\\FSO

1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 2 Set objFolder = objFSO.GetFolder(\"C:\\FSO\")

虽然通配符是不允许的,但是你可以用点来关联到当前的文件夹(.),你可以用点点(..)来绑定到父文件夹,用 \\ 绑定到根文件夹。例如如下代码语句绑定到当前的文件夹: Set objFolder = objFSO.GetFolder(\".\")

※检验文件夹是否存在作者:临汾市外事旅游局薛靖澜,转载请注明出处]

许多的文件夹的操作包括复制、移动、删除需要特定的文件夹存在才可以对其进行操作。毕

页脚内容91

2018年普通高等学校招生全国1卷

竟,脚本不能复制、移动、删除这些不存在的文件夹,如果一个脚本尝试去对一个不存在的文件夹执行类似的操作,那么会报错“path not found”。为了避免这样的问题发生,你可以用 FolderExists 方法来在你绑定一个文件夹之前检查文件夹是否存在。FolderExists 用一个简单的参数(文件夹路径)来返回一个 Boolean 值,如果文件夹存在,返回的值为 True,否则返回的值为 False。作者:临汾市外事旅游局薛靖澜,转载请注明出处]

例如,下例中列出的脚本,FolderExists 方法来检查文件夹 C:\\FSO 是否存在。如果存在,脚本用 GetFolder 方法来绑定文件夹。如果不存在,脚本就弹出一个 message box 说:Folder does not exist.

1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 2 If objFSO.FolderExists(\"C:\\FSO\") Then

3 Set objFolder = objFSO.GetFolder(\"C:\\FSO\") 4 Wscript.Echo \"Folder binding complete.\"

5 Else 作者:临汾市外事旅游局薛靖澜,转载请注明出处] 6 Wscript.Echo \"Folder does not exist?\" 7 End If

※如何建立文件夹

你不可能永远都使用你现有的文件系统结构,从来不去更改你的文件系统结构。而事实上,文件系统是动态的,因为需要变动,现存的文件夹可能被删除,新的文件夹可能被创建。例如,你的单位在 file servers 上给用户提供空间,你需要在每个新用户来的时候创建一个新的文件夹给他。作者:临汾市外事旅游局薛靖澜,转载请注明出处]

FSO给脚本编写者提供了这样的能力,可以让你通过脚本来创建文件夹。例如在上例中脚本检查特定的文件夹是否存在,如果存在,脚本用 GetFolder 的的方法来绑定到这个特定的文件夹,如果不存在,脚本弹出一个消息框。虽然这个方法避免了脚本的失败,但是你或许更希望在文件夹不存在的时候来创建一个文件夹,而不是简单的报告说文件夹不存在。为了做到这点,首先创建一个 FSO 对象实例,然后用CreateFolder 方法,将文件夹的完成路径作为参数,例如,下面脚本用这个方法来创建一个新的文件夹 C:\\FSO 1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 2 Set objFolder = objFSO.CreateFolder(\"C:\\FSO\")

如果文件夹存在,那么会报错说”file exists”。基于此,你需要在创建文件夹的之前检查文件对象是否存在。

Note:FSO 只能在本地创建文件夹。如果你想在远程的计算机上创建文件夹,你需要用到 wshcontroller 对象。你可以在本地创建文件夹然后用 WMI 来将文件夹移动到远程的计算 机上。(这个文件夹只能先创建再用WMI 移动,因为 WMI 不支持创建文件夹的方法。)作者:临汾市外事旅游局薛靖澜,转载请注明出处]

※ 删除文件夹作者:临汾市外事旅游局薛靖澜,转载请注明出处] 当你要删除文件夹时,例如你用文件服务器存储每一个员工的数据,当这个员工离开单位时,他的文件夹将被删除。这保证了文件服务器上的磁盘空间,同样,你或许用一个脚本来创建一个文件夹来存储临时文件,当脚本执行完毕的时候,你会删除这个临时的文件。DeleteFolder方法使你可以删除文件夹和文件夹下的所有文件。DeleteFolder需要一个单独的参数:文件夹的完全路径。例如下面脚本用来删除 C:\\FSO 和其它所有的东西。 1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 2 objFSO.DeleteFolder(\"C:\\FSO\")

这个方法会立即删除所有的文件,它不会让你确认是否需要删除就将其扔到垃圾筒。作者:临汾市外事旅游局薛靖澜,转载请注明出处]

页脚内容91

2018年普通高等学校招生全国1卷

※使用通配符(Wildcards)删除文件夹

脚本的最大的一个优点就是作为一个管理工具,脚本操作可以同时删除许多个项目。例如你可以用脚本的一个单独的操作就可以删除所有的文件和文件夹,而不用一个一个去删除了。 FSO 允许你用通配符来删除一些特定的文件。例如你希望删除某文件夹下所有以 s 开头的文件夹,这可以用下面的命令来完成。当用类似这样的文件夹结构来运行这个的时候,那么文件夹subfolder1,subfolder2,scripts 都会被删除。 objFSO.DeleteFolder(\"C:\\FSO\\S*\")

下面这个脚本用来删除以 su 开头的文件夹,就是说 subfolder1,subfolder2 会被删除。 objFSO.DeleteFolder(\"C:\\FSO\\Su*\")

通配符只能放在文件路径的最末尾。

例如如下代码将通配符放在路径的中间,会报错:path not found objFSO.DeleteFolder(\"C:\\*\\Subfolder1\")

◎VBS脚本运行库手册之四(管理文件夹)

※复制文件夹及文件夹下的内容作者:临汾市外事旅游局薛靖澜,转载请注明出处]

复制文件夹和文件夹当中所有数据能力的对于系统管理任务来说非常重要。有时你需要复制文件夹来创建备份,在计算机 A 和计算机 B 上有同样的文件夹,如果计算机 B 意外的down 掉之后,你就不怕数据丢失了。在其它的时候,你或许希望将含有特定文件的文件夹复制到很多台计算机上。用脚本来向各个计算机复制这个文件夹比手工复制高效的多。作者:临汾市外事旅游局薛靖澜,转载请注明出处]

1、CopyFolder 方法允许你复制一个文件夹到另外一个地方。当不用通配符的时候,这个CopyFolder 的方法和命令 Xcopy /E 命令一样:它拷贝所有的文件和子文件夹,包括空的文件夹。这个命令需要两个参数:源文件夹->这个文件夹可以被确定为本地路径(C:\\Script)或者为 UNC 路径 (\\\\helpdesk\\scripts)。目标文件夹->这个文件夹也可以是本地文件夹和 UNC 路径。如果目标文件夹不存在,那么将自动创建一个文件夹。此外这个方法有个可选的参数:Overwrite,当这个参数存在时,默认的情况下脚本会覆盖已经存在的目标文件夹。

Note:CopyFolder 方法会在遇到错误时停止,即使这个脚本中包含有 On Error Resume Next语句。例如你用脚本用来拷贝 100 的子文件夹,当成功拷贝三个之后,遇到一个错误。这时脚本会中止,它不去尝试剩下的 97 的文件夹。作者:临汾市外事旅游局薛靖澜,转载请注明出处]

在下例中用 CopyFolder 的方法来复制文件夹 C:\\scripts 到 c:\\FSO 并且复写目标文件夹。注意,这个的结果不是 C:\\FSO\\Scripts 而是 C:\\FSO 下有和 C:\\Scripts 有同样的文件。如果你想更改文件夹叫 C:\\FSO\\Scripts,你应该将目标文件夹改为 C:\\FSO\\Scripts 1 Const OverWriteFiles = True

2 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 3 objFSO.CopyFolder \"C:\\Scripts\" , \"C:\\FSO\" , OverWriteFiles

Note:因为这个 CopyFolder 是一个单独的操作,你没有办法来跟踪它的进程。你只是需要简单的等待操作的结束。如果你想监视 copy 命令的过程,你应该用 shell 应用程序。 ※使用通配符(Wildcards)复制文件夹

用这个CopyFolder 命令也可以拷贝所有文件夹和子文件夹下的文件。这样可能导致一个问题,如果只是想拷贝 C:\\FSO 下的文件,而不是想拷贝C:\\FSO\\Subfolder1,C:\\FSO\\Subfolder2,C:\\FSO\\Sbufolder3 下的文件。 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

可是,不幸的是这里没有直接的办法来不拷贝子文件夹中的文件而只是拷贝父文件夹中的文

页脚内容91

2018年普通高等学校招生全国1卷

件,你可以用通配符来限制子文件夹的拷贝。例如如下的脚本代码只是拷贝以 log 字母开头的文件夹。但是,你用通配符的时候就只是拷贝那些符合特定要求的文件夹才被拷贝: objFSO.CopyFolder \"C:\\Scripts\\Log*\" , \"C:\\Archive\

当上面的脚本代码执行的时候,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 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 2 objFSO.MoveFolder \"C:\\Scripts\" , \"\\\\helpdesk\\management\"

注意用 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 浏览器中更改文件夹的名字效果是样的。作者:临汾市外事旅游局薛

页脚内容91

2018年普通高等学校招生全国1卷

靖澜,转载请注明出处]

例如,下例中的脚本将文件夹C:\\FSO\\Samples更改为C:\\FSO\\Scripts在脚本运行之前,Sample 是 C:\\Scripts的文件夹,在脚本运行之后,就是C:\\FSO的子文件夹了。此外Scripts (FSO 下的)含有原来 Sample 所有的文件和子文件。作者:临汾市外事旅游局薛靖澜,转载请注明出处]

1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 2 objFSO.MoveFolder \"C:\\FSO\\Samples\" , \"C:\\FS

◎VBS脚本运行库手册之五(文件夹属性)

※获得文件夹属性作者:临汾市外事旅游局薛靖澜,转载请注明出处]

因为文件夹是一个 COM 对象,它们的属性可以被获得和列举出来,为了列举详细的文件夹信息,你可以用文件夹对象,它是 FSO 的组件之一。文件夹对象的属性列举在了下表中。 Attributes 关于文件夹的属性信息。 DateCreated 文件夹创建的日期

DateLastAccessed 用户最后访问这个文件夹的日期 DateLastModified 用户最后更改文件夹属性的日期

Drive 磁盘信息包括拖尾符号(比如,C:)标识文件夹所在的磁盘 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

Files 存储在这个文件夹中所有文件的信息。

IsRootFolder Boolean 值来表明这个文件夹是否是根文件夹 Name 文件夹的名字但不包括路径信息 ParentFolder 文件夹存放的父文件夹的名字 Property Description

Path 文件夹的路径

ShortName MS-DOS 类型的文件夹的名字,遵循 8.3 的命名规则。 ShortPath MS-DOS 类型的文件夹的名字,遵循 8.3 的命名规则。 Size 文件夹的大小,单位是 bytes,包含子文件和子文件夹的大小在内。 作者:临汾市外事旅游局薛靖澜,转载请注明出处] SubFolders 第一层的子文件夹。在 Subfolders 中的子文件夹不在此列中。 作者:临汾市外事旅游局薛靖澜,转载请注明出处] Type 对于文件夹的描述 ※列举文件夹的属性

为了得到一个文件夹的属性,一个脚本必须: 1.创建一个 FSO 实例

2.用 GetFolder 的方法绑定特定文件夹 3.用 Echo 的方法显示属性。

当你对一个文件夹的属性进行操作的时候,注意文件的属性和子文件夹的属性是以集合的形式返回的,不是单独返回一个的。此外Attributes 属性返回一个属性值。 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 2 Set objFolder = objFSO.GetFolder(\"C:\\FSO\")

3 Wscript.Echo \"Date created: \" & objFolder.DateCreated

页脚内容91

2018年普通高等学校招生全国1卷

4 Wscript.Echo \"Date last accessed: \" & objFolder.DateLastAccessed 5 Wscript.Echo \"Date last modified: \" & objFolder.DateLastModified 6 Wscript.Echo \"Drive: \" & objFolder.Drive

7 Wscript.Echo \"Is root folder: \" & objFolder.IsRootFolder 8 Wscript.Echo \"Name: \" & objFolder.Name

9 Wscript.Echo \"Parent folder: \" & objFolder.ParentFolder 10 Wscript.Echo \"Path: \" & objFolder.Path

11 Wscript.Echo \"Short name: \" & objFolder.ShortName 12 Wscript.Echo \"Short path: \" & objFolder.ShortPath 13 Wscript.Echo \"Size: \" & objFolder.Size 14 Wscript.Echo \"Type: \" & objFolder.Type

※管理文件夹的属性作者:临汾市外事旅游局薛靖澜,转载请注明出处]

文件系统支持属性的定义。就是文件夹中和文件夹名字和文件夹大小无关的信息。例如如果你在 Windows 浏览器中右击某个数据夹的时候,点 Properties 你就可以访问文件夹的属性了。

FSO 可以返回几个关于文件夹信息的重要属性。这些属性和相应的值,列举在下表中:作者:临汾市外事旅游局薛靖澜,转载请注明出处]

Hidden 2 隐藏,就是在 Windows 浏览器中不可见

System 4 表示它是一个系统文件夹。建议不要更改系统文件夹的内容。 Directory 16 应用到所有的文件夹的标准值。所有可以被 FSO 访问的文件作者:临汾市外事旅游局薛靖澜,转载请注明出处] 夹读有这个值,最小位 16。

Archive 32 存盘的属性用在备份程序中,用来决定文件是否需要备份。 如果这个值 enabling 表示文件夹在下一次增量备份中会备份。如果 是disabling 表示不在下一次增量备份中备份

Compressed 2048 表明这个文件夹是否是压缩的

虽然这些看起来很简单,但是从 FSO返回的数据看起来会让你感到很迷惑。例如,你返回一个文件夹的属性值,你或许会看到20,但是这个值并不是像上面一样的标准值。此外,你可能会获得一个单独的值,虽然这个文件夹有说有的属性。这种情况是,脚本并不是返回如 2,4,16,32,2048 这样的值,而只是返回一个 2102。这是因为这些值是以位图的形式显示的。作者:临汾市外事旅游局薛靖澜,转载请注明出处]

◎VBS脚本运行库手册之六(文件夹属性)

Note:对于属性值,它返回和存储的数据是以位图的形式的。对于位图你应该不会奇怪,比如后缀名为.bmp 的图形文件

Working with Bitmaps作者:临汾市外事旅游局薛靖澜,转载请注明出处]

位图看起来就是一系列的开关。如果特定的开关是关闭的,那么这个开关的值就是 0,如果是开启的,比如文件夹对象吧,它就具有上表中所列出的值。而位图的值就是这些开关的值的总和。如果你用脚本查询这个文件夹的属性,脚本就返回一个值为 16. 与其相反,如果有三个开关是开启的:隐藏(值是2),Directory(值是16),压缩(值是 2048).那么这个位图的值应该是 2+16+2048,或者值是 2066。这个也是用脚本查询的时候返回的值。位图被设计成只是有一种办法来获取特定的值。得到值 2066 的方法只有一个就是压缩和隐

页脚内容91

2018年普通高等学校招生全国1卷

藏。你不可能通过别的数学方法来算得这样的值。作者:临汾市外事旅游局薛靖澜,转载请注明出处]

这个设计可以返回值并且决定哪个开关没有开哪个没有开。这个可以允许你来判断文件夹的哪个属性设定了。如果你得到了这个 2066 的值,那么它的属性就是隐藏压缩的文件夹。幸运的是,你不必去作任何单独的数字运算,你可以用逻辑与 AND 操作来决定哪个开关是否是on 还是 off。例如如下代码查询文件夹是否是隐藏的,如果是回显一个信息框: Hidden folder

If objFolder.Attributes AND 2 Then Wscript.Echo \"Hidden folder.\" End If

或者: If objFolder.Attributes AND 16 Then

下列脚本先绑定文件夹 C:\\FSO,然后回显文件夹属性:

(译者注:这个其实是挨个匹配的,所以你要是测试了两个属性,它都会显示出来的。) 1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 2 Set objFolder = objFSO.GetFolder(\"C:\\FSO\") 3 If objFolder.Attributes AND 2 Then 4 Wscript.Echo \"Hidden folder.\"

5 End If 作者:临汾市外事旅游局薛靖澜,转载请注明出处] 6 If objFolder.Attributes AND 4 Then 7 Wscript.Echo \"System folder.\"

8 End If 作者:临汾市外事旅游局薛靖澜,转载请注明出处] 9 If objFolder.Attributes AND 16 Then 10 Wscript.Echo \"Folder.\"

11 End If 作者:临汾市外事旅游局薛靖澜,转载请注明出处] 12 If objFolder.Attributes AND 32 Then 13 Wscript.Echo \"Archive bit set.\"

14 End If 作者:临汾市外事旅游局薛靖澜,转载请注明出处] 15 If objFolder.Attributes AND 2048 Then 16 Wscript.Echo \"Compressed folder.\"

17 End If 作者:临汾市外事旅游局薛靖澜,转载请注明出处] ※改变文件夹属性

文件夹的每个属性可以看成一个个开关,如果关于隐藏的开关是ON 的,那么这个文件夹就是隐藏的,如果这个开关是 OFF 的,那么这个文件夹就不是隐藏的,你可以选择打开或者关掉它们,对于文件夹的属性也是如此:对于其它的开关,你可以将属性设置为开或者设置为关,你可以用脚本来控制这些开关的,最简单的控制属性开关的办法是用如下的程序: 作者:临汾市外事旅游局薛靖澜,转载请注明出处] 1. 用 GetFolder 的方法来绑定到一个文件夹。

2. 检查你需要更改的值。例如你想隐藏一个文件夹,看这个文件夹是否是已经隐藏了作者:临汾市外事旅游局薛靖澜,转载请注明出处]

3. 如果这个文件夹是隐藏的,用 XOR 操作来将开关转换成非隐藏的。如果这个文件夹不是隐藏的,注意不要用 XOR,如果你用了,开关会被触发,文件夹会中止于隐藏。例如,下列脚本用 AND 来判断文件夹 C:\\FSO 的隐藏属性开关是否开着。如果它是开的,脚本用 XOR 操作来将开关关闭来显示文件夹。

1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\")

页脚内容91

2018年普通高等学校招生全国1卷

2 Set objFolder = objFSO.GetFolder(\"C:\\FSO\") 3 If objFolder.Attributes AND 2 Then

4 objFolder.Attributes = objFolder.Attributes XOR 2

5 End If 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

除非很少的一些情况以外,文件夹用来作为单独存放文件的地方。有时候,这些文件夹是系统需要的。例如操作系统希望在特定的文件夹内找到特定的文件。在其它的一些时候,文件夹是系统管理员管理计算机的一种工具也是用户管理文件的工具。系统管理员可能希望将脚本放在叫做Scripts 的文件夹,将一些 trouble-shooting 的工具放在叫做 Diagnostic Tools 的文件夹。用户或许将他们预算信息放在叫做 Budgets 的文件夹,而将薪水的信息放在叫做 Timecards 的文件夹。当然,文件夹一般是限制使用的,你必须知道这个文件夹是存放的是什么文件。系统管理员需要知道是不是有个特定的脚本存在 C:\\Scripts 文件夹中,用户需要知道是不是有个特定的窗体存在C:\\Budgets 的文件夹中。文件夹对象包含了一些属性可用来返回存储在文件夹内文件集合的信息,为了得到这些信息,你的脚本必须:

1. 创建一个 FSO 对象实例。作者:临汾市外事旅游局薛靖澜,转载请注明出处] 2. 用 GetFolder 的方法来绑定到一个适当的文件夹。 3. 设置一个对象 reference 来指向文件夹的属性

4. 用 For Each 循环来列举出所有的文件和他们的属性。脚本不必去绑定到每一个单独的文件去获得文件的信息。

在下列脚本中返回在文件夹 C:\\FSO 下所有文件的信息并且回显他们的名字和大小: 1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 2 Set objFolder = objFSO.GetFolder(\"C:\\FSO\") 3 Set colFiles = objFolder.Files 4 For Each objFile in colFiles

5 Wscript.Echo objFile.Name, objFile.Size

6 Next 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

对于大多数返回的集合来说,你不能控制输出信息的顺序。就是说你不能将输出的格式定义为按照名字,按照大小或者其它别的原则。如果你想让输出的东西按照特定的格式,你就必须将他们拷贝到数组,目录或者一个 disconnected recordset 然后将他们分类排列。

为了需要知道文件夹中存放的文件,你需要知道文件夹子文件夹,这样,你才能更好的了解文件夹的整体结构。文件夹对象包含了一个 Subfolders 属性,用来放会在文件夹下的 top-level 子文件夹的信息。 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

Top-level 子文件夹是直接在文件夹下面的。在子文件夹中的子文件夹不在这个范围之内。例如,在下例中,只有 Subfolder1 Subfolder2 是文件夹 scripts 的 top-level 的子文件夹。所以,如果用 Subfolders 这个属性来返回值的话,就只是会返回 Subfolder1 和Subfolder2

◎VBS脚本运行库手册之八(管理文件)

Managing Files 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

管理文件系统的最终任务还是归结为管理单独的文件。作为一个系统管理员,你的工作是跟踪存储在计算机上的文件。例如,你需要知道正确的诊断工具是否被复制到了 server 上,你需要知道特定的文件(比如游戏文件或者音乐文件)是否被复制到了文件服务器上了,尽管你用了组策略去阻止他们将文件拷贝到文件的 server。你需要知道是否有的文件放在计算机上已经有几个月没有去访问了,而这些功能通过类似知道磁盘的剩余空间这样的操作是无法

页脚内容91

2018年普通高等学校招生全国1卷

知道的。此外为了跟踪这些文件,你也需要动态的管理他们:需要复制,需要移动,需要重新命名,需要删除。FSO 提供了一些方法来帮助你完成这些管理任务。 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

Binding to a File 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

FSO 给你提供了一些方法,比如 CopyFile,DeleteFile 允许你的脚本不用绑定一个特定的文件就可以对文件实例进行操作。而其它的任务,就需要文件对象。比如,为了获得一些属性,你的脚本首先就需要绑定到一个文件,然后再获得文件的属性。GetFile 方法允许你绑定到一个独立的文件。为了做到这点,你先创建一个 FSO 实例,然后创建一个文件对象。当你用 GetFile 方法的时候,你必须:1、确定文件的路径:这个路径可以是一个本地路径,也可以是一个 UNC 路径(例如:\\\\accounting\\receivables\\scriptlog.txt)在路径当中你不能用通配符也不能有多个文件。用 GetFile 方法你在同一个时刻只能绑定一个单独的文件。2、当绑定的对象分配给一个变量的时候就要用到 Set 这个关键词。 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

例如,下面脚本绑定到了文件:C:\\FSO\\Scriptlog.txt 1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 2 objFSO.GetFile(\"C:\\FSO\\ScriptLog.txt\")

一般来讲,你最好用绝对路径来作 GetFile 的参数。这样确保脚本总是可以在文件中运行。但是,用相对路径也是可以的。例如,如下的脚本代码会绑定到 Scriptlog.txt 会成功,因为脚本和这个文件在同一个文件夹里面: 作者:临汾市外事旅游局薛靖澜,转载请注明出处] objFSO.GetFile(\"ScriptLog.txt\") 同样,下面的代码实例如果这个脚本和这个文件在同一个文件夹也会绑定到 Scriptlog.txt: 作者:临汾市外事旅游局薛靖澜,转载请注明出处] objFSO.GetFile(\".\\ScriptLog.txt\")

注意:FSO 不会用路径环境信息去搜索文件。例如,你可以在命令行中敲如 calc.exe 来打开计算机,而无论你当前的目录是在哪里,因为操作系统默认的情况下去搜索所有的文件的。但是用这个GetFile方法的时候,它不是这样的工作的。

如下脚本除非是在文件夹C:\\Windows\\System32 的文件夹下,否则都不会运行成功的。 作者:临汾市外事旅游局薛靖澜,转载请注明出处] objFSO.GetFile(\"calc.exe\")

有时知道文件是否存在是十分重要的,这个可以作为软件清单的一部分。例如你或许希望检查所有的邮件服务器来看特定的脚本是否存在。用脚本来实现系统管理任务来说,知道脚本存在与否很重要的。比如你或许希望当你复制、移动、删除或者操作不存在的文件的时候,脚本报错。为了避免出现错误,你可以用 FileExists方法来检查文件是否存在。FileExists 方法要求一个单独的参数:文件的路径,然后返回一个特定的 Boolean 值:如果文件存在,返回的是 True,如果文件不存在,返回的是 False。

如下面脚本用 FileExists 方法来检查文件 C:\\FSO\\Scriptlog.txt 是否存在,如果存在,用 GetFile 方法来绑定到这个文件,如果不存在,脚本回显一个 message“file does not exist” 1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 2 If objFSO.FileExists(\"C:\\FSO\\ScriptLog.txt\") Then

3 Set objFile = objFSO.GetFile(\"C:\\FSO\\ScriptLog.txt\")

4 Else 作者:临汾市外事旅游局薛靖澜,转载请注明出处] 5 Wscript.Echo \"File does not exist.?

6 End If 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

你不能用通配符来检查文件夹中特定类型的文件是否存在,你也不能用通配符拉来检查文件

页脚内容91

2018年普通高等学校招生全国1卷

夹中所有的文件。如下面脚本,无论在文件夹 C:\\FSO\\下存在多少文件,都不会报错出来,而是总是返回一个 False. 作者:临汾市外事旅游局薛靖澜,转载请注明出处] WScript.Echo objFSO.FileExists(\"C:\\FSO\\*.*\")

如果你希望遵循一些条件原则检查一些文件而不是基于路径,你有下面两个选择:

1、用 GetFolder 对象来绑定一个文件夹,然后返回文件的属性,这样重复操作直到筛选出你感兴趣的。例如,你可以列举出所有的文件和文件的扩展名,然后跟踪看有多少个后缀名 为.doc 的文件。

2、用 WMI,它允许你创建更多的目标查询。比如选出所有后缀名为.doc 的文件。你可以用计数的办法来返回你要的特定的条目。如果数值是 0,那么,最少有一个是.doc 的文件。 Deleting a File 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

用 FSO 来创建脚本删除文件让你可以自动执行类似与磁盘清理之类的操作。例如,你可以用脚本定期查询和删除所有的临时文件。你也可以依照一些规则来删除文件,比如删除六个月都没有被访问的文件,或者特定的后缀名的文件,比如(.bmp 或者.mp3)你可以首先创建 FSO 对象实例,然后调用 DeleteFile 方法来删除文件,输入文件路径作为参数。 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

如下面脚本删除了文件 C:\\FSO\\Scriptlog.txt

1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 2 objFSO.DeleteFile(\"C:\\FSO\\ScriptLog.txt\")

默认的情况下,DeleteFile 方法不会删除只读文件。事实上,当你尝试删除一个只读文件时,脚本会报错出来。为了避免这样的错误出现,如想删除只读文件的话,需添加强制参数,当强制参数设成 True 的时候,那么 DeleteFile 可以删除任何文件。如下面这行代码可以删除文件 Scriptlog.txt,即使它只是一个只读文件。 1、 objFSO.DeleteFile(\"C:\\FSO\\ScriptLog.txt\ 2、 Deleting a Set of Files

有时候你希望删除特定的、单独的文件。更有可能的是你可能想用脚本来删除一系列的文件。如在周末你或许想删除一些存盘了的日志文件或所有的临时文件。你可以通过通配符来删除一个文件夹之内的一些文件。但是你不能用 DeleteFile 方法来直接删除多个文件夹内部的文件。你可以通过用筛选每个数据夹的办法来逐个删除每个文件夹内部的文件。如果你想删除多个文件夹内部的特定类型的文件(比如删除计算机上全部的.TMP 文件)你应该用 WMI 而不是用 FSO。为了删除一系列文件,调用 DeleteFile 方法,根据文件的名字或者后缀名添加通配符来提供文件夹的路径。例如,下面的代码用来删除文件夹 C:\\FSO 文件夹下的所有后缀名为.doc 的文件。

objFSO.DeleteFile(\"C:\\FSO\\*.doc\")

下面的这行代码用来删除所有文件名带有 log 的文件: objFSO.DeleteFile(\"C:\\FSO\\*log.* \")

正如前面提到的那样,DeleteFile 方法不删除标记为只读的文件。如果你的脚本尝试去删除一个只读的文档,脚本会报错,虽然你用了 On Error Resume Next 语句。例如你想删除 1000 个 txt 文件,并且只有一个文件标记为只读了。当脚本尝试去删除这个文件的时候,会产生一个脚本运行的错误,这个 DeleteFile 方法中止。脚本不去尝试去删除其它的文件,虽然其它的文件不是只读的。因为这个原因,你可以用可选择的:强制参数,将它的值设置成 True。当这个参数设置成 True 的时候,DeleteFile 方法可以删除只读文件。当这个参数被设置成 False 的时候,就不能删除只读文件。

下面脚本用来删除文件夹 C:\\FSO 下的所有文件,为了确保删除包括只读文件在内的文件,强制参数被设置成 True。并且使用了这个 DeleteReadOnly 常量。 作者:临汾市外事旅游局

页脚内容91

2018年普通高等学校招生全国1卷

薛靖澜,转载请注明出处]

1 Const DeleteReadOnly = True

2 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 3 objFSO.DeleteFile(\"C:\\FSO\\*.txt\"), DeleteReadOnly

如果你想删除所有不是只读的文件怎么办呢?在这种情况下,你可以返回一个集合,用文件属性来获得文件属性,是否为只读,如果是就不删除,否则就删除。

◎VBS脚本运行库手册之九(复制和移动文件)

Copying a File 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

拷贝文件,无论是从计算机上的一个文件夹到另外一个文件夹还是从一个计算机到另外一个计算机,都是一个非常常见的管理任务。如你希望拷贝一个监视的脚本到你所有的服务器上面来取代过去的 DLL 文件。CopyFile方法提供了这种任务管理的办法。CopyFile 方法需要两个必备参数和一个可选的参数:

1、Source - 要拷贝的文件的源文件的路径。

2、Destination — 目标文件夹的路径。为了确保在目标文件夹也是同样的名字,将一个脱尾符放在文件夹的结束之前(“ \\ ”)

objFSO.CopyFile \"C:\\FSO\\ScriptLog.txt\" , \"D:\\Archive\\\"

如果你想重新命名该文件,你可以将全路径写成如下的格式:

objFSO.CopyFile \"C:\\FSO\\ScriptLog.txt\" , \"D:\\Archive\\NewFileName.txt\" 如果目标文件夹不存在,则会自动创建。

3、Overwrite可选。默认情况下,CopyFile 方法不能复制到目标文件夹存在的同名文件。这导致错误。比如你要更高的版本覆盖存在的文件,那么将这个参数设置成 True。下面脚本拷贝文件 C:\\FSO\\Scriptlog.txt 到文件夹 D:\\Archive。 The original file, C:\\FSO\\ScriptLog.txt. The copied file, D:\\Archive\\ScriptLog.txt.

为了保证拷贝的正常进行,即使存在 D:\\Archive\\Scriptlog.txt,脚本将可选参数 Overwrite设置成 True(用常量 OverWriteExisting) 1 Const OverwriteExisting = True

2 Set objFSO = CreateObject(\"Scripting.FileSystemObject\")

3 objFSO.CopyFile \"C:\\FSO\\ScriptLog.txt\" , \"D:\\Archive\\\ 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

当你确定一个目标文件夹的时候,脱尾的反斜线是十分必要的。(例如D:\\Archive\\)如果你的反斜线在,那么文件会被拷贝到 Archive 文件夹,如果反斜线不在的话,脚本的 CopyFile尝试去建立一个叫做 D:\\Achive 的文件夹。如果这个文件夹存在,那么会产生一个”Permission denied Error”的错误出来,拷贝的进程会失败的。这个对于只读文件来说也是错误的,虽然你可能将强制参数设置成 True。如果没有反斜线,你必须先将原来的文件删除,然后再调用CopyFile 方法来实现。 Copying a Set of Files

通配符提供了一种拷贝整个文件夹中所有的文件的方法。你可以用脚本复制一些具有共同参数的文件。例如下列脚本拷贝在 C:\\FSO 中所有的 txt 文件到 D:\\Archive. 1 Const OverwriteExisting = True

2 Set objFSO = CreateObject(\"Scripting.FileSystemObject\")

页脚内容91

2018年普通高等学校招生全国1卷

3 objFSO.CopyFile \"C:\\FSO\\*.txt\" , \"D:\\Archive\\\" , OverwriteExisting

在 CopyFile 的方法中添加通配符来拷贝文件的时候,只是拷贝当前文件夹的文件。而用CopyFolder 的方法,正好相反,它也拷贝子文件夹的信息和文件。如下的脚本代码语句拷贝文件夹 C:\\FSO 中所有的文件,而不拷贝子文件夹的信息。 objFSO.CopyFile \"C:\\FSO\\*.*\" , \"D:\\Archive\\\"

Moving a File 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

如你的磁盘空间很低了,你或许希望将文件移动到一个新的位置;如果你的计算机换了规则,你或许希望移动特定的诊断工具取代原来的。在其它的一些情况下,你或许不希望存在这个文件的副本,而是将它移动到一个新的位置。MoveFile 方法让你将文件从一个地方移动到另外一个地方。MoveFile 方法和 CopyFile 的方法类似,你需要创建一个 FSO 对象,然后调用 MoveFile 的方法,需要两个参数: 1、需要移动文件的完整路径

2、需要移动到的目标文件夹的路径,包括脱尾符(反斜线)

下例中脚本将 C:\\FSO\\Scriptlog.log 移动到 D 盘的 Archive 文件夹 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 2 objFSO.MoveFile \"C:\\FSO\\ScriptLog.log\" , \"D:\\Archive\\\" Moving a Set of Files

你也可以用通配符来用一个操作移动多个文件。如为移动所有在文件夹 FSO 中以 data开头的文件,你可以用以下的参数: C:\\FSO\\Data*.*

通配符可以用来移动特定的文件。因为文件的类型一般是用后缀名来标识的。如下例中脚本移动所有的日志文件到 D:\\Archive

1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 2 objFSO.MoveFile \"C:\\FSO\\*.log\" , \"D:\\Archive\\\"

Renaming a File 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

FSO 并没有提供一种直接的方法来重新命名一个文件。但是和 MoveFolder 的方法可以重新命名文件夹一样,你也可以用 MoveFile 的方法来重新命名文件。为了重新命名一个文件,你可以用 MoveFile 的方法,但是目标文件夹应为当前的文件夹。

如在下例脚本中,将Scriptlog.txt 重新命名为 Backuplog.txt。而在技术上是脚本实际上将 C:\\FSO\\Scriptlog.txt 移动到一个新的路径 C:\\FSO\\Backuplog.txt,结果是将文件重新命名了。 1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\")

2 objFSO.MoveFile \"C:\\FSO\\ScriptLog.txt\" , \"C:\\FSO\\BackupLog.txt\" 作者:临汾市外事旅游局

◎VBS脚本运行库手册之十(文件的属性)

文件有些属性对于文件的管理来说十分重要,如属性 DateLastAccssed 告诉你最后打开这个文件的日期。属性Size告诉你文件有多少个 bytes,系统管理员可以通过 windows 资源管理器或者命令行工具去访问文件的属性。虽然这些工具可以返回计算机上文件的信息,但是他们不是被设计成用来保存和操作文件属性的。此外,这些工具大多功能有限,不能使系统管理员很好的通过属性来周期性的清理磁盘或者寻找出满足特定属性的文件集合。

幸运的是,你可以通过 FSO 来获得计算机上任何文件的详细信息。和其它的工具相比,FSO可以让你查询一个文件或者一组文件的信息。 作者:临汾市外事旅游局薛靖澜,转载请注明

页脚内容91

2018年普通高等学校招生全国1卷

出处]

Attributes 文件的位图属性。 DateCreated 文件的创建日期。

DateLastAccessed 数据的最后访问日期。 DateLastModified 数据的最后更改日期。

Drive 磁盘驱动器和托尾符(例如:C:)代表文件存在的磁盘上。 Name 文件的名字,不包含文件的路径

ParentFolder 父文件夹的名字。例如,C:\\Windows\\System32\\Scrrun.dll 的父文件夹名字是 Windows

Path 文件的路径,比如 C:\\Windows\\System32\\Scrrun.dll ShortName MS-DOS类型的文件名,符合8.3 命名规则的。 ShortPath MS-DOS-style 文件名字。符合 8.3 命名规则的。 Size 文件的大小,单位是 bytes Type 文件类型,是在注册表区中对于此文件类型的字符串描述。作者:临汾市外事旅游局薛靖澜,转载请注明出处] 为了访问这些属性,你必须: 1. 创建一个 FSO 对象实例。

2. 用 GetFile 方法创建一个对象的 reference。脚本必须给 GetFile 提供文件的路径参数。 3. 用 Echo(或者其它的处理办法)来表达出文件的属性。

如下面的脚本用 GetFile 的方法来绑定到文件 C:\\Windows\\System32\\Scrrun.dll 然后返回一些它的属性:

1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\")

2 Set objFile = objFSO.GetFile(\"c:\\windows\\system32\\scrrun.dll\") 3 Wscript.Echo \"Date created: \" & objFile.DateCreated

4 Wscript.Echo \"Date last accessed: \" & objFile.DateLastAccessed 5 Wscript.Echo \"Date last modified: \" & objFile.DateLastModified 6 Wscript.Echo \"Drive: \" & objFile.Drive 7 Wscript.Echo \"Name: \" & objFile.Name

8 Wscript.Echo \"Parent folder: \" & objFile.ParentFolder 9 Wscript.Echo \"Path: \" & objFile.Path

10 Wscript.Echo \"Short name: \" & objFile.ShortName 11 Wscript.Echo \"Short path: \" & objFile.ShortPath 12 Wscript.Echo \"Size: \" & objFile.Size 13 Wscript.Echo \"Type: \" & objFile.Type 和文件夹一样,文件有些属性可以通过 FSO 返回和配置,有些属性比如位图属性就不能通过 FSO 来获得的。

Normal 0 没有这样的属性设置为 True。?? Read-only 1 文件为只读。

Hidden 2 文件在 Windows 浏览器中是隐藏的。 System 4 文件是操作系统必须的。

Archive 32 存盘,文件标记为需要备份的。 Alias 64 此文件是其它文件的快捷方式 Compressed 2048 此文件是压缩的。

想获得文件的这些属性,用GetFile 方法来绑定一个文件,在你创建完了这个文件对象的

页脚内容91

2018年普通高等学校招生全国1卷

reference 之后,你可以用逻辑与操作来决定这些属性。如果没有任何属性被设置了,那么这个值就是 0。如下面脚本绑定了文件 C:\\FSO\\Scriptlog.txt 然后检查每个属性并用FSO 返回属性的值。

1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 2 Set objFile = objFSO.GetFile(\"C:\\FSO\\ScriptLog.txt\") 3 If objFile.Attributes AND 0 Then 4 Wscript.Echo \"No attributes set.\" 5 End If

6 If objFile.Attributes AND 1 Then 7 Wscript.Echo \"Read-only.\"

8 End If 作者:临汾市外事旅游局薛靖澜,转载请注明出处] 9 If objFile.Attributes AND 2 Then 10 Wscript.Echo \"Hidden file.\" 11 End If

12 If objFile.Attributes AND 4 Then 13 Wscript.Echo \"System file.\" 14 End If

15 If objFile.Attributes AND 32 Then 16 Wscript.Echo \"Archive bit set.\" 17 End If

18 If objFile.Attributes AND 64 Then 19 Wscript.Echo \"Link or shortcut.\" 20 End If

21 If objFile.Attributes AND 2048 Then 22 Wscript.Echo \"Compressed file.\" 23 End If

Configuring File Attributes

除了列举文件的属性之外,FSO 提供了配置如下属性的一些办法: 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

1、ReadOnly 2、Hidden 3、System 4、Archive

为了配置文件的这些属性,脚本可以用如下的进程: 1. 用 GetFile 的方法绑定一个文件。

2. 检查你要更改的文件的属性。如你想将一个文件设置成只读的那么就检查它是否是已经是已读了。

3. 如果不是只读的,那么用逻辑 XOR 操作来触发这个开关。这样可以使文件变成只读的。但 是如果文件已经是只读的,那么不要用逻辑 XOR 操作,如果你用了,那么这个属性就被移掉了。

下面脚本用 AND 操作来检查只读开关是否已经打开,从而确定文件C:\\FSO\\TestScript.vbs是否为只读。如果为只读,脚本用 XOR 操作来将其改成非只读的。 1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 2 Set objFile = objFSO.GetFile(\"C:\\FSO\\TestScript.vbs\") 3 If objFile.Attributes AND 1 Then

4 objFile.Attributes = objFile.Attributes XOR 1 5 End If

页脚内容91

2018年普通高等学校招生全国1卷

你也用如下的语句来同时去更改系统、存盘、隐藏等属性 objFile.Attributes = objFile.Attributes AN

◎VBS脚本运行库手册之十一(建立文本文件)

Reading and Writing Text Files

文本文件对于系统管理员来说是一个强大的系统管工具。这个对于现在的高级的图形界面和多用户的操作系统来说好象是不可能的。但是,简单的文本文件,比如 notepad 文件,仍然是系统管理的一个关键元素。文本文件是轻便而且便于维护的。他们占用较少的磁盘空间不需要其它多余的软件支持。文本文件可以简单的工作并且非常容易携带。用文本文件写的脚本文件可以被复制和察看任何计算机的信息,虽然它运行的系统不是 Windows.此外,它还提供了快捷,简单,标准的办法来向脚本输入和输出数据。文本文件可以存储向脚本中输入的数据(arguments)或者向脚本中硬编码。这样你就不用向命令行中输入 100 个服务器的名字,脚本可以从文本文件中读这些信息。同样,文本文件为存储脚本获取的信息提供了快捷简单的方法。这些数据可以直接写到数据库,但是这个要求在服务器上作额外的配置,额外的脚本代码,在脚本运行时候额外的管理。但是数据可以存在文本文件中,然后在稍后导入到数据中去。

FSO 提供一些读写文本文件的方法。 Creating Text Files

FSO 让你可以用现存在的文本工作,也可以让你自己创建脚本。为了创建一个新的文本文件,简单的创建一个 FSO 对象,然后调用 CreateTextFile 方法,输入完整的文件路径信息作为这个方法的参数。

例如,如下的脚本代码在文件夹 C:\\FSO 中创建了一个 Scriptlog.txt 的文件: 作者:临汾市外事旅游局薛靖澜,转载请注明出处] Listing 4.32 Creating a Text File

1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\")

2 Set objFile = objFSO.CreateTextFile(\"C:\\FSO\\ScriptLog.txt\")

如果这个文件存在,那么 CreateTextFile 方法会创建一个。如果这个文件已经存在,那么CreateTextFile 方法会复写存在的文本文件,而以新的空白的文件取代它。如果你希望这个文件不被取代,那么就用一个可以选择 Overwrite 的参数。当这个参数设置成 False 的时候,攒在的文件就不被复写。当这个参数被设置成 True(默认的是 True),那么就会复写存在的文件。例如,如下的脚本如果创建的文件存在的话就不会复写。 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

Set objFile = objFSO.CreateTextFile(\"C:\\FSO\\ScriptLog.txt\

如果你将参数设置成 False,并且文件存在,那么就会有一个运行的错误。因为如此,你可以检查文件是否存在,如果存在,那么就作其它的操作,例如允许用户更改一个新的文件名。 Creating File Names Within the Script

防止文件存在产生错误的方法是用脚本给文本文件生成一个名字。因为文件名字生成器并不创建

一个有意义的名字,这对于你想在未来要命名的日志和其它文件来说不是一个好的办法。但是,这个对于需要临时文件的脚本来说保证了有个特定的文件名。例如,你或许想让你的脚本将数据保存在 HTML 或者 XML 格式,然后将这些数据在 WEB 浏览器中显示,然后将这个临时文件在web 浏览器关掉时删除。在这种情况下,你可以用 GetTempName 方法来生成

页脚内容91

2018年普通高等学校招生全国1卷

一个特有的文件名。

为了生成一个特别的文件名,脚本首先要创建一个 FSO 对象实例然后调用 GetTempName 方法(不用参数。)例如在 4.33 中的脚本用一个 For Next 循环来随机生成 10 文件名字。 Listing 4.33 Creating a File Name

1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 2 For i = 1 to 10

3 strTempFile = objFSO.GetTempName 4 Wscript.Echo strTempFile

5 Next 作者:临汾市外事旅游局薛靖澜,转载请注明出处] 当脚本在 CScript 下运行的时候,输出的命令行和下面的类似: rad646E9.tmp radEC50C.tmp rad0C40A.tmp radE866E.tmp rad77F3D.tmp rad19970.tmp rad7A21A.tmp radB9DDC.tmp rad84930.tmp rad92199.tmp

Note 作者:临汾市外事旅游局薛靖澜,转载请注明出处] 用 GetTempName 来生成文件的名字生成的不是唯一的。部分原因是生成名称的算法,部 分是因为可能的名字的数量是有限的。文件名字被限制为 8 个字节,而且前三个字节规定为 rad,例如,你用脚本来创建 10000 个文件名字,在第 9894 个文件名字之后就不再是唯一的了,剩下的 106 个 53 对是复制的。

在 4.34 中的示例脚本用 GetTempName 方法来创建一个文件,脚本必须: 1. 创建一个 FSO 对象实例。

2. 创建一个给文件夹 C:\\FSO 的变量叫做 strPath.

3. 用 GetTempName 方法来生成一个单独的文件名子。

4. 用 BuildPath 的方法来合并文件夹名字和文件名字来创建一个完成的临时文件的名字。这个 整个路径存储在 strFullName 变量中。 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

5. 调用 CreateTextFile 方法,用 strFullName 来作参数。

6. 在创建了这个文件之后,关闭这个文件。在生产环境中,大多数情况下,你可能要向里面写 了数据之后再关闭它。

Listing 4.34 Creating and Naming a Text File

1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 2 strPath = \"C:\\FSO\"

3 strFileName = objFSO.GetTempName

4 strFullName = objFSO.BuildPath(strPath, strFileName) 5 Set objFile = objFSO.CreateTextFile(strFullName) 6 objFile.Close 作者:临汾市外事旅游

页脚内容91

2018年普通高等学校招生全国1卷

◎VBS脚本运行库手册之十二(打开和关闭文本文件)

Opening Text Files 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

用文本文件来工作有三个主要的步骤。在你可以作其它的事情之前,你必须打开文本文件。这个你可以打开存在的文件或者创建一个新的文本文件,创建结束之后,默认文件是打开的。每个方法都是返回一个 TextStream 对象实例。

在你获得了 TextStream 对象之后,你可以向这个文件中写或者读这个文件。但是你不能向同一个文件读和写。换句话说,在同一个操作中,你不能打开一个文件,读这个文件然后再向这个文件中写东西。你必须读完这个文件后关闭,然后再打开这个文件,写入数据,然后关闭。 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

当你打开一个存在的文件,这个文件要么是准备好被读的,要么是准备好被写的。如果你创建一个新的文本文件,这个文本文件只是被读的,没有什么其它原因的话,它没有内容去被读。最后,你要去关闭这个文本文件,虽然它不是必须的,因为在脚本结束的时候,它会自动关闭,但是这个对于程序实践来说是个好的办法 为了打开一个文本文件: 1. 创建一个 FSO 对象实例。

2. 用:OpenTextFile 来打开一个文本文件。这个 OpenTextFile 需要两个参数,一个是一个文 件的路径,另外一个是跟着的参数:

For reading (parameter value = 1, constant = ForReading).

文件被打开之后只是被用来为读作准备的,为了写这个文件,你必须再一次的打开文件,用参数 ForWriting 或者 ForAppending。

For writing (parameter value 2, constant = ForWriting).

文件被打开,并且写入的数据覆盖了原来存在的数据,就是说旧的数据被删除,新的被添加。用这个方法用新的数据来代替存在的数据。作者:临汾市外事旅游局薛靖澜,转载请注明出处]

For appending (parameter value 8, constant = ForAppending).

文件在这种模式下打开,并且新的数据添加到文件的末尾。用这个方法向存在的文件中添加新的数据。

当打开文件的时候,你必须使用适当的参数。当你用读的模式打开一个文件而试图向里面写东西的时候,你会收到一个 bad file mode 的错误。你如果试图打开一个非文本文件的话也会收到同样的错误的。你可以直接用数值(比如 1 代表写)或者创建一个常量然后赋值给它适当的值。例如,如下的两种方法都可以打开一个文件并且准备被读:作者:临汾市外事旅游局薛靖澜,转载请注明出处] Const ForReading = 1

Set objFSO = CreateObject(\"Scripting.FileSystemObject\")

Set objFile = objFSO.OpenTextFile(\"C:\\FSO\\ScriptLog.txt\ Set objFile2 = objFSO.OpenTextFile(\"C:\\FSO\\ScriptLog2.txt\ 但是在没有定义这个常量的时候,你不能直接用。这是因为事实上 VB 脚本并没有这些 COM 对象常量。如下的脚本会返回一个 invalid procedure call or argument 的错误并且失败。这是因为ForReading 这个常量并没有显式的定义。因为它没有定义,所以这变量默认情况下被赋值为 0,而 0 对于 OpenTextFile 来说并不是一个合法的参数: Set objFSO = CreateObject(\"Scripting.FileSystemObject\")

Set objFile = objFSO.OpenTextFile(\"C:\\FSO\\ScriptLog.txt\作者:临汾市外事旅游局

页脚内容91

2018年普通高等学校招生全国1卷

薛靖澜,转载请注明出处]

在 4.35 中的脚本打开了 C:\\FSO\\Scriptlog.txt 准备读,用了用户自己定义的变量,并且赋值为 1.

Listing 4.35 Opening a Text File for Reading 1 Const ForReading = 1

2 Set objFSO = CreateObject(\"Scripting.FileSystemObject\")

3 Set objFile = objFSO.OpenTextFile(\"C:\\FSO\\ScriptLog.txt\作者:临汾市外事旅游局薛靖澜,转载请注明出处] Closing Text Files

所有的用脚本打开的文本文件在脚本结束的时候会自动关闭。因为如此,比不是必须的去显式的关闭一个文本文件。然而,关闭这个文本文件却是一个很好的程序实践并且在下面的一些情况下,如果不关闭文件的话,会产生一些错误。

◎VBS脚本运行库手册之十三(读取文本文件)

Reread the file.

有些时候你或许希望用一个脚本多次读一个文件。你或许打开一个文本 文件然后将它所有的内容全部保存给一个字符串变量,然后搜索这个字符串来查找特定的错误的代码。当这个错误找到了,你再逐行去读取文件,提炼出有错误的每一行。如果你尝试多次去读一个文件,你不会收到你期待的结果,而是会遇到一个运行的错误。例如下的脚本读取一个文本文件,返回文件的内容到屏幕,然后尝试重复这样的过程: Set objFSO = CreateObject(\"Scripting.FileSystemObject\") Set objFSO = CreateObject(\"Scripting.FileSystemObject\") Set objFile = objFSO.OpenTextFile(\"C:\\FSO\\ScriptLog.txt\ Wscript.Echo \"Reading file the first time:\" strContents = objFile.ReadAll Wscript.Echo strContents

Wscript.Echo \"Reading file the second time:\" Do While objFile.AtEndOfStream = False strLine = objFile.ReadLine Wscript.Echo strLine Loop

当在 cscript 下运行的是命令行的信息如下: Reading file the first time: File line 1. File line 2. File line 3.

Reading file the second time:

第一次文件是被读取的,内容存储在变量 strContents 上,第二次,文件读取的时候,没什有数据回显在屏幕上,这是因为文件已经到达了文件的末尾,没有其它的数据给你读了。为了读取这个数据,你必须关闭这个文件然后重新打开它。你不能在读到文件的末尾之后去跳到文件的开头去了。TextStreamObject Close 方法用来关闭一个文本文件。例如,在 4.36 中的脚本创建一个FSO 对象实例,然后打开一个文本文件,然后在立即关闭了。为了访问文件

页脚内容91

2018年普通高等学校招生全国1卷

的内容,你必须再一次的调用 OpenTextFile 方法去重新打开这个文件。 Listing 4.36 Opening and Closing a Text File

1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 2 Set objFile = objFSO.OpenTextFile(\"C:\\FSO\\ScriptLog.txt\ 3 objFile.Close Reading Text Files

在许多的企业脚本中,读取文本文件的内容是个标准进程,你可以用这个功能来读取命令行的参数。例如,你的文本文件包含了计算机名字的列表,脚本审计成读取这个列 表,然后在每个计算机上运行这个脚本。搜索满足特定条件的日志文件。例如,你或许想找所有有错误的日志。将日志文件中添加内容并且汇入到数据库。例如,你或许有一个服务或者程序来保存信息到特定存文本文件格式。然后你用脚本来读取这个文件拷贝相关的信息到数据库中。 可以用 FSO 来都读取文本文件的内容,但是有以下几点你需要牢记:FSO 只能读取 ASCII 的文本文件。你不能用 FSO 读取unicode 或者 binary 文件格式的文件,比如 microsoft word 或者是 Microsoft excel .用 FSO 读取文本文件的时候,只能有一种方式:从前到后。此外,FSO 读取文件的时候是逐行读取的。如果你试图返回前面的行,你必须从开始再重新读取,直到特定的行。 你不能打开一个文件同时用来读和写。如果你打开一个文件是为了读的,那么你想修改文件内容的时候,你必须重新打开文件。如果你尝试在写的模式下读取文件,那么你会收到一个 bad file mode 的错误。

还有读取特定的字符然后停止也是我们常用的技巧。例如,如下的命令会读取第一行的前 12 个字符Alerter.Shar,并且将它赋值给变量 strText,然后停止:strText = objTextFile.Read(12) ReadLine 读取文本文件中每行的信息然后在到达新的一行的之前停止。例如,如下的命令读取第一行并且将它赋值给变量strText,然后停止。strText = objTextFile.ReadLine 为了逐行读取整个文件的内容,将 ReadLine 放在一个循环中。 ReadAll Reads the entire contents of a text file into a variable.

Skip 跳过特定的数目的字符之后停止。例如,如下的命令面跳过前面的 12 字节,后操作都说从第 13 个字符开始。 objTextFile.Skip(12)

SkipLine 跳过一整行。例如,如下的代码先读第一行,然后读取第三行。跳过了第二行 strText = objTextFile.Readline objTextFile.SkipLine

strText = objTextFile.Readline

◎VBS脚本运行库手册之十四1(把文本文件当作数据库来对待)

虽然在单独的一个字符串中寻找东西是很简单,但是不是要求特别快。用 ReadAll 方法在读 取近 6000 行的测试文件的时候,每秒钟搜索大约 388kb。逐行读取的话也会小于一分钟的。 为了用 ReadAll 方法,打开一个文本文文件,然后调用 ReadAll 方法(不用参数的)例如在 4.38的脚本,打开文件 C:\\FSO\\Scriptlog.txt,然后读取文件的内容,蒋数据存储在变量 strContents 中,脚本然后回显这个变量的值,就是回显了文本文件的内容。 Listing 4.38 Reading a Text File Using the ReadAll Method 1 Const ForReading = 1

2 Set objFSO = CreateObject(\"Scripting.FileSystemObject\")

3 Set objFile = objFSO.OpenTextFile(\"C:\\FSO\\ScriptLog.txt\

页脚内容91

2018年普通高等学校招生全国1卷

4 strContents = objFile.ReadAll 5 Wscript.Echo strContents 6 objFile.Close

Reading a Text File Line by Line

为了达到系统管理的目的,文本文件有的时候像一个扁平的上数据库一样的工作。每一行代表数据库的一个纪录。例如,脚本经常在文本文件中读取服务器的名字,然后针对这些服务器来执行操作。在这些情况下,文本文件看起来和下面这些差不多的: atl-dc-01 atl-dc-02 atl-dc-03 atl-dc-04

当文本文件当做扁平数据库的时候,脚本被用来读取每个纪录然后针对每个纪录作一些工作。例如,一个脚本或许读取第一个计算机名子,连接到它,实现一些功能。然后这个脚本读取第二个计算机的名字,连接到它,然后实现同样的功能。这个进程直到读取完了所有的计算机名字,然后结束。

ReadLine 方法可以让你的脚本读取文本文件中单个的行。为了这个方法,打开一个文本文件,然后用一个 Do Loop 循环直到文件的 AtEndOfStream 属性为真。在这个循环中,调用ReadLine 方法,存储第一行的内容到一个变量,然后作一些动作。当脚本执行循环的时候,热它自动丢弃第一行的内容读取第二行的内容到这个变量。这个过程持续进行直到文件的结束。

例如,在 4.39 中的脚本打开文件 C:\\FSO\\Serverlist.txt 然后逐行读取整个文件,将内容回显在屏幕上:

Listing 4.39 Reading a Text File Using the ReadLine Method 1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\")

2 Set objFile = objFSO.OpenTextFile(\"C:\\FSO\\ServerList.txt\ 3 Do Until objFile.AtEndOfStream 4 strLine = objFile.ReadLine 5 Wscript.Echo strLine 6 Loop

7 objFile.Close

\"Reading\" a Text File from the Bottom to the Top

正如前面提到的,FSO 只能从文本文件的前面读到后面,你不能从后面向前面读。这个对于日志文件来说有一些问题,大部分的日志文件是按照日期格式来写的,它的最开始的第一个日志被纪录在第一行,第二个纪录纪录在第二行,依次类推。这就以为着你感兴趣的事情,最新的日志往往在文件末尾。

有的时候你希望按照反日期的顺序来显示信息,就是最近的纪录最先显示,最旧的纪录最后显示。虽然你不能从后面先前的读取文本文件,但是你要可以实现上面的目的,脚本必须: 1. 创建一个数组来存储文本文件的每行信息

2. 用 ReadLine 的方法读取文本文件的每行信息,然后将每行的信息作为数组的一个独立的元 素存储在数组中。

3. 在屏幕上显示数组的信息,从数组的最后面开始,向前显示。

例如,在 4.40 中的脚本读取文件 C:\\FSO\\Scriptlog.txt 的信息,然后将每行的信息作为数组 的一个元素存储在数组 arrFileLine 中。在整个文件被读了之后,从数组的最后一个开始回显数组的信息。为了做到这点,用了一个 for 循环,从数组的最后一个元素,the upper bound of

页脚内容91

2018年普通高等学校招生全国1卷

array 逐渐增长到第一个元素,the lower bound of array 1 Dim arrFileLines() 2 i = 0

3 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 4 Set objFile = objFSO.OpenTextFile(\"C:\\FSO\\ScriptLog.txt\ 5 Do Until objFile.AtEndOfStream 6 Redim Preserve arrFileLines(i) 7 arrFileLines(i) = objFile.ReadLine 8 i = i + 1 9 Loop

10 objFile.Close

11 For l = Ubound(arrFileLines) to LBound(arrFileLines) Step -1 12 Wscript.Echo arrFileLines(l) 13 Next

如果文件的内容和下面的一样: 6/19/2002 Success 6/20/2002 Failure 6/21/2002 Failure 6/22/2002 Failure 6/23/2002 Success

那么在屏幕上回显的信息如下: 6/23/2002 Success

6/22/2002 Failure 6/21/2002 Failure 6/20/2002 Failure 6/19/2002 Success

Reading a Text File Character by Charact

◎VBS脚本运行库手册之十四2(写入文本文件)

在一些定宽的文本文件中,区域是受长度的限制的。第一个 field1 或许包含 15 个字节,第 2个 field 或许含有十个,依次类推。那么这样的文件看起来和下面的差不多: Server Value Status atl-dc-0119345 OK

atl-printserver-02 00042 OK atl-win2kpro-0500000 Failed

在有些情况下,你或许只是想获得 values 的值或者只是想获得 status 的信息。这个 value 的信息,容易表明。Values 总是从第 26 个字符开始,不超过 5 个字符。为了获得这些值,你只需要获得第 26,27,28,29,30 个字符的信息。

方法 Read 允许你读取特定数目的字节。它的一个单独的参数就是你要读的字节的个数。例如,

如下的脚本代码示例,读取后面的 7 个字节,并将读取的值存给变量 strCharacters: strCharacters = objFile.Read(7)

页脚内容91

2018年普通高等学校招生全国1卷

用 Skip 和 SkipLine 方法,你可以获得文本文件中你选择的特定字符。例如,在脚本 4.41 中 只是读取每行的第 6 个字节。为了做到这点,脚本必须: 1. 跳过每行前面五个字节用 Skip(5) 2. 用 Read(1)读取第 6 个字节 3. 跳到下面一行。

Listing 4.41 Reading a Fixed-Width Text File

1 Set objFSO = CreateObject(\"Scripting.FileSystemObject\") 2 Set objFile = objFSO.OpenTextFile(\"C:\\FSO\\ScriptLog.txt\ 3 Do Until objFile.AtEndOfStream 4 objFile.Skip(5)

5 strCharacters = objFile.Read(1) 6 Wscript.Echo strCharacters 7 objFile.SkipLine 8 Loop

为了更好说明脚本是如何工作的,我们假设脚本文件 C:\\FSO\\Scriptlog.txt 看起来是如下的样子的:

XXXXX1XXXXXXXXXXXXXX

XXXXX2XXXXXXXXXXXXXXXXXXX XXXXX3XXXXXXXXXXXXx

XXXXX4XXXXXXXXXXXXXXXXXXXXXXXXX

对于这个文件的每行,前面的五个字符都是 x,第六个是数字,后面是随机数量的 x。当脚本4.41 运行的时候,脚本会:

1. 打开文本文件从第一行开始读起。 2. 跳过前面五个字符。

3. 用 Read 载方法读取第六个字符 4. 回显字符在屏幕上

5. 跳到下面一行重复上面的进程,直到脚本运行结束。. Writing to Text Files

像文本文件中写入数据是写系统管理脚本的另外一个强大的功用。文本文件提供了一种方法可以让你将脚本获得的输入存储在其中。输入可以替代现有的文字或者是添加到现有的文字后面。文本文文件也可以纪录脚本的执行情况。这个对于 debug 脚本来说费城有用。将脚本的执行纪录放在一个文本文件中,你可以过阵子来察看这个日志去决定脚本实际执行了哪些而哪些没有执行。FSO 给你提供了向文本文件中写如数据的能力。为了用 FSO 脚本向一个文本文件中写入数据,你必须: 1. 创建一个 FSO 对象实例。

2. 用 OpenTextFile 方法打开这个文本文件,你可以以两种方法打开: For writing (parameter value 2, constant = ForWriting).

在这个模式下,写入新的数据会覆盖旧的数据。(旧的数据会被删除,新的数据添加上去。) 用这个模式,是将存在的文件换上新的内容。

For appending (parameter value 8, constant = ForAppending).

在这种模式下,数据写在原来文件的末尾。用这种模式向现有的文件中添加数据。 3. 用或者 Write,WriteLine,WriteBlankLine 方法来向文本文件中写入数据。. 4. 关闭文本文件

向文本文件中写数据的三种方法在表格 4.9 中:

页脚内容91

2018年普通高等学校招生全国1卷

Table 4.9 Write Methods Available to the FileSystemObject Method Description

Write 向文本文件中写入数据,不是添加文件到末尾。不会自动换行。 例如,如下代码写入两个单独的字符串: objFile.Write (\"This is line 1.\") objFile.Write (\"This is line 2.\") MethodDescription

返回的数据类似如下: This is line 1.This is line 2.

WriteLine 向文本文件中写入数据后添加一个换行符号,然后区自动换行的。 比如,如下的代码:

objFile.WriteLine (\"This is line 1.\") objFile.WriteLine (\"This is line 2.\") 结果输出的信息如下: This is line 1. This is line 2.

WriteBlankLines 向文本文件中写入特定数目空白的行。例如如下的代码向文本文件中写入两行独立的文字,然后用空白的行分开: objFile.Writeline (\"This is line 1.\") objFile.WriteBlankLines(1)

objFile.Writeline (\"This is line 2.\") 输出的结果如下: This is line 1. This is line 2.

除了在表格 4.9 中的方法之外,VB 脚本提供了常量 VbTab 来向文本文件中写入。VbTab 向两个字符中插入一个空格。为了创建一个空格分隔的文件,代码和下面的类似: objTextFile.WriteLine(objService.DisplayName & vbTab & objService.State)

FSO 的一个弱点就是它不能直接修改特定的行的信息。你不能写类似下面的命令:跳过到第五行,更改一些数据,然后保存成新的文件。为了修改在一个十行文件中的第五行,你的脚本必须

1. .读取整个 10 行

2. .将 1-4 行写回文件。

3. 写入修改好的第五行的内容。 4. 写入第 6 行到第 10 行的内容。

◎VBS脚本运行库手册之十五(追加文本)

Overwriting Existing Data

在系统管理中,简洁是一种美德。例如,假如你的脚本每天晚上运行,在你的 DC 上从事件日志中获得日志,将这些事件写入数据库中,纪录哪个计算机可以成功的连接到,哪个不可以。基于一些历史的目的,你或许希望跟踪明年一整年的所有成功和失败的纪录。这个对于脚本刚开始生效和网络不稳定的情况下来说,都是非常重要的。从另外的情况来说,你或许只是希望刚才脚本运行的时候发生了什么。换句话说说,你不是希望要一个日志中过去的 365

页脚内容91

2018年普通高等学校招生全国1卷

天的信息,而是要距离最近的信息。它让你可以很快的打开文件并且查找看脚本是否按照计划的运行。 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

当你的文本文件用 ForWriting 模式打开的,任何写入的新的数据会替代原来存在的文件。例如,假如你的文本文件里面存储了整个莎士比亚的故事全集,但是你用脚本以 ForWriting 模式打开了这个文本,并且向里面写了一个字母 a,那么当你的这个文件写完关闭之后,它就只是包含一个字母 a,原来的数据就全部丢失了。

这个脚本以 ForWriting 模式打开脚本 C:\\FSO\\Scriptlog.txt 然后将当前的日期和时间写入文件。每当脚本运行的时候,旧的时间和日期被新的取代,这个文本文件就永远只是有单独的一个日期的值。

Listing 4.42 Overwriting Existing Data 1 Const ForWriting = 2

2 Set objFSO = CreateObject(\"Scripting.FileSystemObject\")

3 Set objFile = objFSO.OpenTextFile(\"C:\\FSO\\ScriptLog.txt\ 4 objFile.Write Now 5 objFile.Close

Appending New Data to Existing Data

许多脚本被设计成为在特定的时间间隔的时候运行,收据数据,保存数据。这些脚本的是用来分析趋势或者在过去的时间内部的使用情况。在这些情况下,你就不希望删除现在存在的数据而去替代成新的数据。 作者:临汾市外事旅游局薛靖澜,转载请注明出处] 例如,假如你用你的脚本监视进程使用量。在任何一个时间点上,进程的使用量应该是在 0 到100 之间的一个值,对于它自己来说,单个的值没有什么意义。为了获得进程使用的一个完整的图景,你需要重复不断的监视使用情况并纪录它的值。如果你的进程在每几秒钟之内返回的数据是9%,17%,92%,90%,79%,88%,91%那么你的进程使用是非常高的。这个就可以对比出这个时间内的使用情况。

如果以 ForAppending 的模式打开一个文件,你可以使数据不是覆盖现有的数据,它的数据是添加到文件的底部。例如,在 4.43 中的脚本打开一个文本文件,并且将当前的日期和时间写入文件。因为是以 ForAppending 的模式打开的文件,当前的日期会卸载文件的底部。如果你在不同的时候分别运行脚本,你的脚本结束时候大约如下面的信息: 作者:临汾市外事旅游局薛靖澜,转载请注明出处] 6/25/2002 8:49:47 AM 6/25/2002 8:49:48 AM 6/25/2002 8:50:33 AM 6/25/2002 8:50:35 AM

Listing 4.43 Appending Data to a Text File 1 Const ForAppending = 8

2 Set objFSO = CreateObject(\"Scripting.FileSystemObject\")

3 Set objFile = objFSO.OpenTextFile(\"C:\\FSO\\ScriptLog.txt\ 4 objFile.WriteLine Now

5 objFile.Close 作者:临汾市外事旅游局薛靖澜,转载请注明出处]

上面的脚本用 WriteLine 方法写入数据保证每个日期都是独占一行的。如果这个脚本用 Write 的方法来写的话,那么这个脚本运行结束的时候,数据写在一起,如下的样子: 6/25/2002 8:49:47 AM6/25/2002 8:49:48 AM6/25/2002 8:50:33 AM6/25/2002 8:50:35 AM

页脚内容91

2018年普通高等学校招生全国1卷

◎VBS脚本运行库手册之十六(Dictionary 对象之一)

Dictionary Object

脚本经常用来从外面的源获得信息,例如从文本文件或者数据库文件。在这些信息获得之后,它将被存储到它的内存中,然后用脚本来更改它。例如将信息存储在一个变量中,或者存储在一个数组中。同样,这些信息可以存储在 Dictionary 对象中。Dictionary 就好象一个数组一样。不同的是,它用叫做键对(key-item pairs)来存储信息,而数组用数字值来存储。例如,一个一维的数组存储州的首府像下面这样:作者:临汾市外事旅游局薛靖澜,转载请注明出处]

0 - Olympia 1 - Salem

2 - Sacramento

于其相反,Dictionary 存储信息像如下的格式: Washington – Olympia Oregon - Salem

California - Sacramento

如果你的命令行只是要求输入一个参数,比如计算机名字,你可以用数组来完成这样的工作。但是,Dictionary 提供了比数组更加多的功能。特别指出的是,Dictionary 不要求一个脚本确定需要存储的元素的数目。在数组中,你必须确定数组的大小,或者当添加数据的时候重新变更数组的大小。知道每个值对应的 index。在 Dictionary 中,值可以通过 key 或者 item 自身来访问。 这样,当管理员用脚本从外部获得信息,比如获得计算机的名字,然后存储在内存中以备使用的时候,Dictionary 就成了一个理想的工具。 Creating a Dictionary

因为 Dictionary 是一个 COM 对象,你必须用其它的 COM 对象那样去初始化它。如下的代码创建一个 Dictionary 对象。

Set objDictionary = CreateObject(\"Scripting.Dictionary\")

当创建完了一个 Dictionary 对象之后,你可以配置 Dictionary 的属性或者向其内部添加元素。

Configuring Dictionary Properties

Dictionary 只有一个配置的属性,CompareMode,它对于要添加哪个 KEY 或者不能添加哪个 KEY起着非常重要的作用。(检查 key 是否存在在 Dictionary 中也是十分重要的)默认的情况下,Dictionary 是被创建成二进制模式,基于 ASCII 的值。知道这个很重要,因为在 ASCII 中,大写和小写字符是不同的。在二进制中,如下的两个服务可以同时被添加进来: alerter 作者:临汾市外事旅游局薛靖澜,转载请注明出处] ALERTER

换句话说,在二进制模式下,你可能因为大小写不同而添加进来很多个同样的 item。这样就难于搜索了。如果你想查找 Alerter 这个 KEY,你可能得到它不存在,因为没有和它大小写完全一样的值。这样你可能向一个 Dictionary 添加同样的 item。当一个 Dictionary 被配置成 text 模式的时候,大小写被认为是一样的,这样可以除去同样的 key,你的 Dictionary 如果存在 alerter 的话,你就不能向其中添加另外一个叫做 ALERTER 的 key。无论你搜索 alerter 还是 ALERTER,都会找到叫做 Alerter 的 key。

为了配置 Dictionary 的模式,首先创建一个 Dictionary 对象实例,然后配置它的属性为如下的值:

页脚内容91

2018年普通高等学校招生全国1卷

0-设置成为二进制模式,这个是默认选项。 1 – 设置成 text 模式。

例如,如下的 4.44 的脚本设置 Dictionary 成 text 模式: Listing 4.44 Configuring the Dictionary Object 1 Const TextMode = 1

2 Set objDictionary = CreateObject(\"Scripting.Dictionary\") 3 objDictionary.CompareMode = TextMode 在 Dictionary 有任何元素的时候,你不能更改 Dictionary 的 CompareMode 属性。这是因为,二进制允许大小写的区分,例如,如下的 keys 每个代表了不同 key,因为 Dictionary 是基于二进制格式的: 作者:临汾市外事旅游局薛靖澜,转载请注明出处] apple Apple APPLE

在 text 模式下,这些 keys 是一致的。如果你将这些元素存储在二进制格式,那么没有什么问题,但是存储在 text 模式下的时候,Dictionary 就突然之间有三个同样的 keys,它就会失败了。

如果你想配置 Dictionary 的模式,那么事先移走 Dictionary 中所有的元素。 Adding Key-Item Pairs to a Dictionary 在创建了 Dictionary 对象实例之后,你可以用 add 方法向 Dictionary 添加 key-item 对。Add方法需要两个参数,必须按照如下顺序并且用逗号分开: Key name Item value

例如,在脚本 4.45 中,创建了一个 Dictionary 对象,然后添加一些类似于表格 4.10 中的key-item 对。

Table 4.10 Sample Key-Item Pairs

Key Item 作者:临汾市外事旅游局薛靖澜,转载请注明出处] Printer 1 Printing Printer 2Offline Printer 3Printing

Listing 4.45 Adding Key-Item Pairs to a Dictionary

1 Set objDictionary = CreateObject(\"Scripting.Dictionary\") 2 objDictionary.Add \"Printer 1\ 3 objDictionary.Add \"Printer 2\ 4 objDictionary.Add \"Printer 3\

Dictionary 的 key 必须是唯一的。例如,如下的两个语句会产生一个运行的错误出来。在第一行被编译之后,叫做 printer 1 的 key 已经存在于 Dictionary 中了: objDictionary.Add \"Printer 1\ objDictionary.Add \"Printer 1\

◎VBS脚本运行库手册之十七(Dictionary 对象之二)

Inadvertently Adding a Key to a Dictionary 使用 Dictionary 对象的一个潜在的问题是,你如果去访问一个在 Dictionary 中不存在的元素

页脚内容91

2018年普通高等学校招生全国1卷

的时候,它不产生一个错误,而是将这个不存在的元素添加到 Dictionary 中去了。看下面的脚本示例,它创建了一个 Dictionary,添加了三对 key-item,然后尝试去回显不存在的item,printer 4:

Set objDictionary = CreateObject(\"Scripting.Dictionary\") objDictionary.Add \"Printer 1\ objDictionary.Add \"Printer 2\ objDictionary.Add \"Printer 3\ Wscript.Echo objDictionary.Item(\"Printer 4\")

当脚本尝试去回显不存在的 item 的时候,没有任何运行错误发生,而是创建了一个新的 key,printer 4,并被添加到了 Dictionary 中,它的对象的 item 的值是 null。 为了避免这样的错误发生,在访问 item 的值的时候,去检查它是否存在。 Manipulating Keys and Items in a Dictionary

作为 Dictionary 本身而言,它的用途很少。一个 Dictionary 只有在访问它的 item,列举它的item,或者修改它的 item 的时候,才变得有用。在你创建了一个 Dictionary 之后,你可能作如下的一些事情:

确定在这个 dictionary 中有多少对 key-item 对列举出在 dictionary 的 keys 和或者 item。 决定在 Dictionary 是否存在特定的 key

修改在 Dictionary 中的 key 或者 item 的值 从 Dictionary 中移除特定 key-item 对。

所有这些任务都可以通过在 RunTime Library 中提供的属性方法来实现。 Determining the Number of Key-Item Pairs in a Dictionary 和其它的许多集合一样,Dictionary 有一个 count 属性用来返回在这个集合中的 key-item 对的数量。在脚本 4.46 中创建了是个 Dictionary 对象,然后添加三个 key-item 对,回显这个Dictionary 的 count 属性的值。

Listing 4.46 Determining the Number of Key-Item Pairs in a Dictionary 1 Set objDictionary = CreateObject(“Scripting.Dictionary”) 2 objDictionary.Add “Printer 1”, “Printing” 3 objDictionary.Add “Printer 2”, “Offline” 4 objDictionary.Add “Printer 3”, “Printing” 5 Wscript.Echo objDictionary.Count 当脚本运行的时候,会显示一个值 3 Enumerating Keys and Items in a Dictionary

Dictionary 被设计成用来暂时的存储信息。任何存在 Dictionary 中的信息都是作为临时用的,没有用来长期存储的。它一般是用来临时放信息,然后在脚本中在重新调用他们。例如,你有个存储了服务器名称清单的 Dictionary,然后在后面的脚本中连到这些服务器上,并且获得相应的信息。结果是,你每次连接到一个服务器的时候,你都必须去调用 Dictionary 中的信息。

Keys items 的方法可以用来返回他们的组成集合,或者的单独的返回或者全部返回在Dictionary 中的 item-key 的信息。在你用了其中的一个方法之后,你可以用 For Each 循环列举除在数组中所有的 key-item。

例如在 4.47 中的脚本创建一个简单的 Dictionary,添加三对 keys-item,在这个 Dictionary 创建结束之后,脚本用 keys 方法来列举出所有的 keys,然后用 items 方法来返回所有的 items Listing 4.47 Enumerating Keys and Items in a Dictionary

1 Set objDictionary = CreateObject(\"Scripting.Dictionary\")

页脚内容91

2018年普通高等学校招生全国1卷

2 objDictionary.Add \"Printer 1\ 3 objDictionary.Add \"Printer 2\ 4 objDictionary.Add \"Printer 3\ 5

6 colKeys = objDictionary.Keys 7 For Each strKey in colKeys 8Wscript.Echo strKey 9 Next 10

11 colItems = objDictionary.Items 12 For Each strItem in colItems 13 Wscript.Echo strItem 14 Next

当脚本在 CScript 下运行的时候,命令行的信息如下: Printer 1 Printer 2 Printer 3 Printing Offline Printing

为了显示特定的 item 的值,用 item 方法,例如,如下的代码语句显示了 key 是 printer 3 的item 的值:

Wscript.Echo objDictionary.Item(\"Printer 3\")

◎VBS脚本运行库手册之十八(Dictionary 对象之三)

Verifying the Existence of a Specific Key

Dictionary 的一个比数组更加优秀和标准的优点是你可以快速的找到特定的 key 是否存在。例如,假如你有一定的文件 list 安装在一个计算机上,并且你向搜索这个 list,来保证特定的 dll文件已经安装了。你用集合或者数组,除非你系统的搜索整个数组否则你没有方法来确定特定的一个文件是否存在了。但是用 Dictionary 你可以 Exists 方法来检查给定的 key 是否存在。用Exists 方法只是需要一个参数,(需要查询的 key 的名字),然后返回一个 Boolean 的值,如果是真的值,表明这个 key 存在,如果是否,则不存在。

例如,在脚本 4.48 中创建一个 Dictionary 对象,添加三对元素,然后脚本检查叫做 key 的关键词是否存在,并且回显其结果。

Listing 4.48 Verifying the Existence of a Dictionary Key 1 Set objDictionary = CreateObject(\"Scripting.Dictionary\") 2 objDictionary.Add \"Printer 1\ 3 objDictionary.Add \"Printer 2\ 4 objDictionary.Add \"Printer 3\ 5 If objDictionary.Exists(\"Printer 4\") Then 6Wscript.Echo \"Printer 4 is in the Dictionary.\" 7 Else

页脚内容91

2018年普通高等学校招生全国1卷

8Wscript.Echo \"Printer 4 is not in the Dictionary.\" 9 End If

当脚本运行的时候,会有 printer 4 is not in the Dictionary 的消息出现在屏幕上. Modifying an Item in a Dictionary

添加到 Dictionary 中的 item 不是一成不变的,事实上,你可以在任何的时间去更改它。这个功能可以让你纪录脚本的运行情况。例如,你的 Dictionary 是个关于服务器名称的列表区,每次你的脚本对应的服务器运行结束之后,你可以更改它对应的 item 值来标识它的状态。在脚本中止之前,你可以将状态列出来看脚本运行成功与否的。在 4.49 中的脚本创建了一个具有三个 keys 的 Dictionary,这三个 key 分贝为 atl-dc-01,atl-dc-02,atl-dc-03,每个的 item 都是设置成 no status,这个表明针对这个服务器的状态信息还没有获得。然后回显他们的 item的信息。

在这个 Dictionary 被创建之后,用 item 方法以 key 作为参数更改这些 item 的值。例如,如下的脚本代码语句更改 key atl-dc-01 的 item 为 available:: objDictionary.Item(\"atl-dc-01\") = \"Available\"

在这三个 items 的值被更改了之后,新的 item 被回显出在屏幕上: Listing 4.49 Modifying the Value of a Dictionary Item 1Set objDictionary = CreateObject(\"Scripting.Dictionary\") 2objDictionary.Add \"atl-dc-01\ 3objDictionary.Add \"atl-dc-02\ 4objDictionary.Add \"atl-dc-03\ 5

6colKeys = objDictionary.Keys 7For Each strKey in colKeys

8Wscript.Echo strKey, objDictionary.Item(strKey) 9Next 10

11 objDictionary.Item(\"atl-dc-01\") = \"Available\" 12 objDictionary.Item(\"atl-dc-02\") = \"Available\" 13 objDictionary.Item(\"atl-dc-03\") = \"Unavailable\" 14

15 colKeys = objDictionary.Keys 16 For Each strKey in colKeys

17 Wscript.Echo strKey, objDictionary.Item(strKey) 18 Next

当在 Cscript 下运行这个的时候,命令行中的信息如下: atl-dc-01 No status atl-dc-02 No status atl-dc-03 No status atl-dc-01 Available atl-dc-02 Available atl-dc-03 Unavailable

Removing Key-Item Pairs from a Dictionary

Key-item 对也可以从 Dictionary 中移走,Script Runtime Library 提供了移走 key-item 对的两种方法:

页脚内容91

2018年普通高等学校招生全国1卷

RemoveAll, 移走所有的 key-item 对

Remove, 从 Dictionary 移走特定的 key-i

◎VBS脚本运行库手册之十九(Dictionary 对象之四)

Removing All Key-Item Pairs from a Dictionary

你或许有一些脚本,比如监视的脚本,作着同样的动作,将信息存在一个 Dictionary 中,然后要么在屏幕上显示这些信息,要么将这些信息存储在文本文件中或者数据库中。然后,脚本停止几分钟,收集更新了之后的信息,就这样不确定的进行下去了。

如果你用 Dictionary 来作为临时的数据存储收集信息数据,你可能希望在收取新的信息之前清空 Dictionary 的内容。为了做到这点,你可以用方法 RemoveAll 来移走所有的 Dictionary中的 key-item 对。例如,在 4.50 中的脚本创建了一个含有三个元素的 Dictionary,然后显示 Dictionary 的 keys,脚本用 RemoveAll 方法移走所有的 key-item 对,objDictionary.RemoveAll

为了检查元素是否被移走,在此回显 Dictionary 中 key 的信息Listing 4.50 Removing All the Key-Item Pairs in a Dictionary

1 Set objDictionary = CreateObject(\"Scripting.Dictionary\") 2 objDictionary.Add \"Printer 1\ 3 objDictionary.Add \"Printer 2\ 4 objDictionary.Add \"Printer 3\ 5 colKeys = objDictionary.Keys 6 Wscript.Echo \"First run: \" 7 For Each strKey in colKeys 8Wscript.Echo strKey 9 Next

10 objDictionary.RemoveAll 11 colKeys = objDictionary.Keys

12 Wscript.Echo VbCrLf & \"Second run: \" 13 For Each strKey in colKeys 14 Wscript.Echo strKey 15 Next

当脚本在 CScript 运行的时候,如下的信息显示在命令行中。和你看见的一样,第二次输出的时候是空的,因为 Dictionary 已经没有任何的 keys 了。 First run: Printer 1 Printer 2 Printer 3 Second run:

Removing a Specific Key-Item Pair from a Dictionary

和移走所有的 key-item 对不同,你有的时候可能向移走一个单独的 key 和 item。例如,假如你的脚本来从一系列的计算机上获得时间日志。脚本被设计成尝试联系每个计算机跟踪每个成功和失败。如果不能连接到计算机上,脚本尝试重新连接,知道连接到计算机并获得所有的日志信息。在这个假想的情况下,可能你的 Dictionary 中有如下的 keys:

页脚内容91

2018年普通高等学校招生全国1卷

atl-dc-01 atl-dc-02 atl-dc-03 atl-dc-04 atl-dc-05

当脚本运行的时候,它可能不能连接到计算机 atl-dc-03,atl-dc-04,在这种情况下,脚本去尝试重新连接这些计算机。但是脚本怎么知道哪个计算机需要连接,哪个不需要那?

一个解决的办法就是简单的移走已经成功连接的计算机。在第一段脚本被编译结束之后,那这个Dictionary 中只是包含如下的元素: atl-dc-03 atl-dc-04

一旦一个计算机连接成功,就从 Dictionary 中移走这个元素,这样,如果 Dictionary 中不再含有任何元素的时候,那么所有的计算机就都连接成功了,脚本运行结束了。

为了移走单个的元素,用 Remove 方法,输入 key 的名字作为唯一的参数。例如如下的脚本语句移走了 key 为 atl-dc-02 的 key 和它对应的 item。 objDictionary.Remove(\"atl-dc-02\")

在 4.51 中的脚本创建一个有三个元素的 Dictionary 对象,回显所有的 keys。然后移走 key为 printer 2 的 key 和它的 item,然后再次回显 Dictionary 的 keys: Listing 4.51 Removing a Specified Key-Item Pair from a Dictionary 1 Set objDictionary = CreateObject(\"Scripting.Dictionary\") 2 objDictionary.Add \"Printer 1\ 3 objDictionary.Add \"Printer 2\ 4 objDictionary.Add \"Printer 3\ 5 colKeys = objDictionary.Keys 6 Wscript.Echo \"First run: \" 7 For Each strKey in colKeys 8Wscript.Echo strKey 9 Next

10 objDictionary.Remove(\"Printer 2\") 11 colKeys = objDictionary.Keys

12 Wscript.Echo VbCrLf & \"Second run: \" 13 For Each strKey in colKeys 14 Wscript.Echo strKey 15 Next

当脚本在 CScript 运行的时候,在命令行中显示如下: First run: Printer 1 Printer 2 Printer 3 Second run: Printer 1 Printer 3

在第二段脚本编译的末尾,printe

页脚内容91

2018年普通高等学校招生全国1卷

第四章 ◎使用脚本部件向导简化WSC设计

尽管XML语言被设计成为一种相对精简的标记语言,符合XML格式的WSC部件也设计的极为规范,但就我而言,在具体的设计过程中,出错最多的仍然在XML的各种标记上,幸好,微软推出了专门生成WSC部件代码的工具Windows Script Component Wizard,这个工具可以迅速的为我们搭建好WSC部件的框架,极大的方便了我们对WSC部件的编写,此向导除了在微软的网站上下载外,在我的网盘上也有一份拷贝。

它的使用方法也极为简单,就连诸如我之流E文程度极差者也能使用。 如上例,生成如下代码:

description=\"测试用的WSC部件\" progid=\"test.WSC\" version=\"1.00\"

classid=\"{155642f0-fbad-4f98-90cb-b38b7a3cf428}\" >

呵呵,该有的东西全有了,属性对应的变量也定以来,我们只要对其中实现部分稍加修改就可以注册应用了,需要注意的是,如果在WSC编码设计中出现汉字,则必须在第一行添加encoding=\"gb2312\"标记,既第一行为:

才能正常通过注册。

第五章 ◎简单WSC组件的基本结构

WSC是微软公司提供的使用脚本语言来创建 COM 部件的便利途径,它可以应用于支持 COM 部件的应用程序。WSC采用XML语言编写。一个标准的WSC组件本身涉及到XML标记相当复杂,但幸好它的结构非常规范,了解结构,填入代码,一个WSC脚本部件就可以工作了。

就我个人而言,把WSC部件分成三个部分:注册部分,定义属性、方法、事件部分和实现部分。

1、注册部分:

主要包含了向注册表注册部件时需要填写的信息。一般包含了部件描述、版本信息、progid、clsid等四个内容。基本格式如下:

description=\"部件描述的信息\" version=\"部件的版本号\"

progid=\"XXXX.XXX\" /程序ID clsid=\"xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx\"/> 需要说明的是:

①registration是XML标记。

②progid是VBS通过CreateObject函数通过绑定组件创建实例时的标志,一

页脚内容91

2018年普通高等学校招生全国1卷

个组件如果没有ProgId,几乎是无法使用的。例如:

Set obj=CreateObject(\"scripting.filesystemobject\") 代码中的scripting.filesystemobjec就是ProgId。 ③Clsid是部件在注册表项中的唯一标志,系统注册时把有关部件的信息放在注册表中,应用时通过读取注册信息,应用程序可以找到并载入该部件。可以使用Uuidgen.exe 的程序随机生成。当然如果你不指定Clsid,系统注册时regsvr32会为它自动创建一个,但正常情况下应该指定一个。由于我的计算机上没有安装VC,所以Uuidgen.exe和GUIDGen.exe文件,Clsid从一直是我极为头疼的问题,幸好UMU给出了一个脚本产生,现把代码抄录如下:

Dim objSLTL

Set objSLTL = CreateObject( \"Scriptlet.TypeLib\" ) Wscript.echo objSLTL.GUID Set objSLTL = Nothing

2、定义属性、方法、事件部分

在这个部分定义了用户在脚本中可以使用的属性、方法、事件,其基本结构如下:

其中Public是XML的标记,property、method、event标记分别定义了部件属性、方法、事件。Name标记定义了其名称,Parameter标记定义了其参数。作为property标记来说,本身带有两个子标记,它们分别是,它们两个分别定义了读写属性的方式。当需要读写属性的时候,就会自动执行它们中的一个。在实现部分中,它们会以Put_属性名 或者 Get_属性名的形式出现。如果忽略了标记,则此属性是只可写的,忽略了标记,说明此属性是只读的。作为vbs脚本,在脚本中响应事件的机会是比较少的,对此也就不再详细的说明。

3、实现部分

在上一部分定义的所有的属性、方法、事件的实现函数都必须包含在

抛开XML的标记不管,我们只需要有关的部分进行修改就可以了。在Public部分定义的属性和方法,在本部分必须定义相应的变量和函数。

当然,WSC作为一个XML格式的文件,一些基本的标记还是需要知道的,下面有关标记说明摘自微软。

元素: 元素包含的是一个完整的脚本部件定义。在同一个 .wsc 文件中可以出现多个 元素,但这些元素应包含在一个 元素内。

元素:包括用来将脚本部件注册为 COM 部件的信息。

元素:包含脚本部件所说明的属性、方法和事件的定义。这些定义指向定义在独立的

用代码调用

Set test=CreateObject(\"ID\") test.du=5 Test.xie 显示正常

页脚内容91

因篇幅问题不能全部显示,请点此查看更多更全内容

Top