1.概述

  Windows Script Host除了提供一个对象模型之外,还提供了一种脚本框架,这就是WSF脚本。通过WSF约定的标记元素,可以将多种脚本语言写的代码块组合起来,完成任务。除此之外,还可以实现一些DOS没有的命令功能,通过CScript xxx.wsf /?来查看帮助文档,帮助文档由WSF声明并由解释器动态生成完整的文档。再联合使用WshEnvironment对象,即可对DOS命令,随心所欲的提供增量功能实现了。

2.WSF标记

元素 语法 属性 备注
<?job?>
<?job error="flag" debug="flag" ?>
error=>布尔值;默认值false;当error="true"时,就允许 Windows脚本(.wsf)文件中存在语法错误或运行时错误。
Debug=>布尔值;默认值false;当debug="true"时,就启用调试,出错时,将启动脚本调试程序。
父元素<job>
<?XML?>
<?XML version="version"
[standalone="DTDflag"] ?> 
version=>n.n形式,指定文件的XML级别。默认值1.0。

DTDflag=>可选,布尔值;指明 XML 文件中是否包括对外部文档类型定义 (DTD) 的引用。脚本组件 XML
文件不包括这样的引用,因此该属性值始终是 "yes"。 
可选,须放于第一行。通过不用,否则,脚本中的大于号和小于号,将被错误处理
<description> <description>text</description> text=>文本【可多行】,用于描述脚本用途,即用法文档的第一行 父元素<runtime>
<example> <example>text</example> text=>文本,用于提供简单的脚本调用示例

父元素<runtime>
<job> <job
[id=JobID]>code</job> 
JobID=>作业id,须是合法标识符,且在当前程序中惟一 只有一作业的wsf脚本,无需父元素<package>,可以很多个
<named> <named name = namedname
helpstring = helpstring
  type =
"string|boolean|simple"  
required = boolean/>
name=>字符串;参数名,将传入Wscript.Arguments.Named中
helpstring=>文本;此参数的说明文档。WSH运行时使用ShowUsage()或 /? 来获取这里定义的参数文档。

type=>可选。限定参数的类型,参数的类型定义如何从命令行分析参数。默认值为simple;string即字符串,boolean用+/-表示true/false;simple时,没有value,如"dir
/b"这个"b"命名参数,就是无值的
required=>可选,布尔值;指明某个参数是否必需的。

父元素<runtime>,可以很多个
<object>
<object id="objID"
[classid="clsid:GUID" | progid="progID"] />
objID=>合法惟一的标识符。用于引用脚本中该对象的名称。
GUID=>可选。对象的类 ID (GUID)。
progID=>可选。对象的程序 ID,可指定它来替换类 ID。
父元素<job>,如<obect
id="fso"
progid="Scripting.FileSystemObject"/>,脚本中就可直接使用fso,而不用再声明此对象;可以是很多个
<package> <package>jobs</package>  jobs=>一个或多个<job>元素 当有多个作业(Job)时,必须使用
<reference>
<reference
[progid="progID"|guid="typelibGUID"]
[version="version"] />
progID=>
可以派生出类型库的程序ID。它可以包含一个版本号(例如,ADO.Recordset.2.0),即类型库的显式程序
ID,也可以包含与类型库合并的可执行文件(如 .DLL)的程序 ID。如果使用对象属性,就无需指定版本属性,因为可从程序 ID
中推断版本。如果指定了对象属性,就不能同时指定 GUID 属性。
typelibGUID=>要引用的类型库的 GUID。如果指定了 GUID 属性,就不能指定对象属性。
version=>可选。要使用的类型库的版本号。它的形式必须为
<主要版本>[.<次要版本>]。如果未指定版本,则默认版本为 1.0。如果对象属性用于指定类型库,且未指定版本,则版本会从指定程序
ID 的注册表项中派生。如果未找到任何信息,则默认版本为 1.0。 
父元素<job>,可以有很多个,一个job的引用,在另一个job的代码中不可见
<resource> <resource
id="resourceID">textornumber</resource>
resourceID=>脚本中资源的唯一标识符,内容是文本或数字 可以有很多个,父元素<job>,一个job的资源,在另一个job的代码中不可见
<runtime> <runtime>
  
<description>text<description>
   <named attributes etc.
/>
   <unnamed attributes etc.
/>
  
<example>text</example>
</runtime>
  ShowUsage()使用由 <runtime>
元素括起来的信息,以便显示脚本的运行时参数。父元素<job>
<script> <script
language="language"
[src="strFile"]>code</script> 
language=>声明用于脚本块中的脚本语言名称,如
VBScript 或 JavaScript。
strFile=>要包括在脚本块中的脚本文件名,如c:\\a.js
父元素<job>,可以有很多个,语言不必相同
<unnamed> <unnamed name = unnamedname

helpstring = helpstring
 many = boolean required = boolean/
integer/>
name=>用于在用法中表示该参数的字符串。该值不用在别处。

Helpstring=>此参数的说明文档。WSH运行时使用ShowUsage()或 /? 获取参数文档

many=>可选,布尔值。如果为true,则该参数重复的次数可以比由required属性指定的次数多;否则,required属性正好表示要使用所需参数的次数。

Required=>可选。指明该参数在命令行中出现次数的整数值。 

当设置“必需”属性时,布尔值将被转换成整数;"true"
变成 1,而 "false" 变成 0。可以有很多个。比如<unnamed name="filename" helpstring="..." many="false" required="true" />生成文档example.wsf filename;比如<unnamed name="filename" helpstring="..." many="false" required="3" />生成文档example.wsf filename1 filename2 filename3
<usage> <usage>text</usage> text=>用于替代WSH根据<runtime>元素中其它元素动态生成的文档 父元素<runtime>

3.自定义命令行工具示例

  1. <package>
  2. <job id="js">
  3. <resource id="dbpath">C:\Users\nutix\Desktop\Persons.xml</resource>
  4. <object id="fso" progid="Scripting.FileSystemObject" />
  5. <object id="xml" progid="MSXML2.DomDocument" />
  6. <object id="ws" progid="WScript.Shell" />
  7. <runtime>
  8. <description>Write the base information of a person to the database</description>
  9. <named name="name" helpstring="name of person." type="string" required="true" />
  10. <named name="sex" helpstring="sex of person." type="string" required="true" />
  11. <named name="age" helpstring="age of person." type="string" required="true" />
  12. <unnamed name="note" helpstring="note of person" many="false" required="false" />
  13. <example>Test.wsf /name:"John Smith" /sex:Male /age:32 "Got some trouble!"</example>
  14. </runtime>
  15. <script language="JScript">
  16. var argsNamed = WScript.Arguments.Named;
  17. var argsUnnamed = WScript.Arguments.Unnamed;
  18. WScript.Echo("There are " + argsNamed.length + " named arguments:");
  19. for(var e=new Enumerator(argsNamed);!e.atEnd();e.moveNext()){
  20. var name=e.item();
  21. WScript.Echo("['"+name+"']="+argsNamed.Item(name));
  22. }
  23. WScript.Echo("There are " + argsUnnamed.length + " unnamed arguments:");
  24. for(var i=0;i<argsUnnamed.length;i++){
  25. WScript.Echo('['+i.toString()+']:'+argsUnnamed.Item(i));
  26. }
  27. WScript.Echo("There are " + WScript.Arguments.length + " arguments in total:");
  28. for(var e=new Enumerator(WScript.Arguments);!e.atEnd();e.moveNext()){
  29. WScript.Echo(e.item());
  30. }
  31. WScript.Arguments.ShowUsage();
  32. //==============================================================
  33. var argsNeeded=new Array('name','sex','age');
  34. for(var i=0;i<argsNeeded.length;i++)
  35. if(!argsNamed.Exists(argsNeeded[i])){
  36. WScript.Echo('Error: Full information is needed, like name, sex, age.');
  37. WScript.Quit();
  38. }
  39. dbpath=getResource('dbpath');
  40. if(!fso.FileExists(dbpath)){
  41. xml.loadXML('<?xml version="1.0" encoding="utf-8"?><Persons />');
  42. xml.save(dbpath);
  43. }
  44. //--------------------------------------------------------------
  45. xml.load(dbpath);
  46. var doc=xml.documentElement
  47. var person=xml.createElement('Person');
  48. var nameAttr=xml.createAttribute('name');
  49. nameAttr.text=argsNamed.Item('name');
  50. person.setAttributeNode(nameAttr);
  51. var sexAttr=xml.createAttribute('sex');
  52. sexAttr.text=argsNamed.Item('sex');
  53. person.setAttributeNode(sexAttr);
  54. var ageAttr=xml.createAttribute('age');
  55. ageAttr.text=argsNamed.Item('age');
  56. person.setAttributeNode(ageAttr);
  57. if(argsUnnamed.length!=0&&argsUnnamed.Item(0)!='')
  58. person.text=argsUnnamed.Item(0);
  59. doc.appendChild(person);
  60. xml.save(dbpath);
  61. //--------------------------------------------------------------
  62. ws.Run('Notepad.exe "'+dbpath+'"');
  63. </script>
  64. </job>
  65. <job id="vbs">
  66. <script language="VBScript">
  67. WScript.Echo getResource("dbpath")
  68. </script>
  69. </job>
  70. </package>

执行“Test.wsf /?”的结果如下:

  1. Write the base information of a person to the database
  2. 用法: Test.wsf /name:value /sex:value /age:value [note]
  3.  
  4. 选项:
  5.  
  6. name : name of person.
  7. sex : sex of person.
  8. age : age of person.
  9. note : note of person
  10. Test.wsf /name:"John Smith" /sex:Male /age:32 "Got some trouble!"

第1行,最前一行直接显示<description>的内容

第2行,由WScript.exe或CScript.exe根据<runtime>元素的各个子元素提供的信息,动态生成的调用方式

第6-9行,是由WScript.exe或CScript.exe根据<runtime>元素的各个<named>/<unnamed>元素提供的信息,生成的参数说明,即<参数名>:<description>

第10行,最后一行直接显示的是<example>元素的内容。

因为note参数required="false",所以它不是必须的,所以上面的文档中显示的是"[note]"而不是"note"

在命令窗口中执行以下的命令:

cscript //nologo Test.wsf /name:"John Smith" /sex:Male /age:32 "Got some trouble!"

输出:

  1. There are 3 named arguments:
  2. ['name']=John smith
  3. ['sex']=Male
  4. ['age']=32
  5. There are 1 unnamed arguments:
  6. [0]:Got some trouble!
  7. There are 4 arguments in total:
  8. /name:John smith
  9. /sex:Male
  10. /age:32
  11. Got some trouble!
  12. Write the base information of a person to the database
  13. 用法: Test.wsf /name:value /sex:value /age:value [note]
  14.  
  15. 选项:
  16.  
  17. name : name of person.
  18. sex : sex of person.
  19. age : age of person.
  20. note : note of person
  21. Test.wsf /name:"John Smith" /sex:Male /age:32 "Got some trouble!"

第12-21行,是WScript.ShowUsage()方法的结果。

可见,如果一个WSF脚本中包含多个<job>,而在调用时没有指定调用哪个job,就默认会执行第一个job的所有<script>块的代码。如果想调用第二个job,可以执行cscript //nologo //job:vbs Test.wsf,其结果如下:

  1. C:\Users\nutix\Desktop\test.wsf(68, 14) Microsoft VBScript 运行时错误: 无效的过程调用或参 数: 'getResource'

显然这里无法访问//Job:js中的resource.

4.组合不同语言的代码

【1】通过<script>块的src引用外部代码

  1. <package>
  2. <job id="IncludeExample">
  3. <script language="JScript" src="GetFreeSpace.JS"/>
  4. <script language="VBScript">
  5. '获得驱动器 C 的可用空间。
  6. s = GetFreeSpace("c:")
  7. WScript.Echo s
  8. </script>
  9. </job>
  10. </package>

GetFreeSpace.js的代码:

  1. function GetFreeSpace(drvPath) {
  2. var fs, d, s;
  3. fs = new ActiveXObject("Scripting.FileSystemObject");
  4. d = fs.GetDrive(fs.GetDriveName(drvPath));
  5. s = "Drive " + drvPath + " - " ;
  6. s += d.VolumeName;
  7. s += " Free Space: " + d.FreeSpace/1024 + " Kbytes";
  8. return s;
  9. }

【2】直接将不同语言的代码写进同一个WSF脚本文件中,这只需要使用多种语言的<script>块就行了。

5.WSH文件,这是一种简单的配置文件,它的作用和脚本文件右键》属性》脚本选项卡的内容一样,可设置项很少很简单,下面是一个例子:

  1. [ScriptFile]
  2. Path=C:\Users\nutix\Desktop\a.js
  3. [Options]
  4. Timeout=0
  5. DisplayLogo=1
  6. BatchMode=0

注意:Path指定的脚本文件必须存在,且可以被WScript或CScript解释执行。其它设置项:Timeout:设置超时时间,超时时自动终止执行,DisplayLogo:是否显示徽标,BatchMode:是否以批处理模式执行

6.使用WSF替代VBS/JS的理由:

【1】可联合使用VBS/JS的标准库

【2】可更友好的支持命令行:可提供充足详实的命令行文档及调用控制

【3】可方便地导入现有的代码模块

【4】可更方便地对功能进行集成:借助<Job>元素

【5】支持直接向网页的移植

【6】更便利的跨语言的全局对象,只要不同语言的<Script>块处于同一个<Job>块中,这个块中的全局变量是跨语言公用的

WSF脚本详解:组合JS和VBS代码的更多相关文章

  1. HTML滚动字幕代码参数详解及Js间隔滚动代码

    html文字滚动代码 <marquee style="WIDTH: 388px; HEIGHT: 200px" scrollamount="2" dire ...

  2. FLASH动作脚本详解

    FLASH动作脚本详解 一.FLASH脚本基础入门讲解 二.按钮AS的编写 三.影片剪辑的AS编写 四.动态文本框 五.影片剪辑的拖拽 六.流程控制与循环语句 七.绘图及颜色的AS的编写 八.声音 A ...

  3. 【转】IOS AutoLayout详解(三)用代码实现(附Demo下载)

    转载自:blog.csdn.net/hello_hwc IOS SDK详解 前言: 在开发的过程中,有时候创建View没办法通过Storyboard来进行,又需要AutoLayout,这时候用代码创建 ...

  4. (转)Uri详解之——Uri结构与代码提取

    前言:依然没有前言…… 相关博客:1.<Uri详解之——Uri结构与代码提取>2.<Uri详解之二——通过自定义Uri外部启动APP与Notification启动> 上几篇给大 ...

  5. Uri详解之——Uri结构与代码提取

    目录(?)[+] 前言:依然没有前言…… 相关博客:1.<Uri详解之——Uri结构与代码提取>2.<Uri详解之二——通过自定义Uri外部启动APP与Notification启动& ...

  6. Day04 dom详解及js事件

    day04 dom详解 DOM的基础 Document对象 Element对象 Node对象 innerHTML 事件处理 表单验证   上次课内容回顾: JS中ECMAScript用法: JS定义变 ...

  7. MySQL命令行下执行.sql脚本详解

    本文主要介绍一个在MySQL命令行下执行脚本文件的例子,通过这个例子让我们来了解一下在命令行下MySQL是怎样执行脚本的吧.现在我们开始介绍这一过程. 1.首先编写sql脚本,保存为的:book.sq ...

  8. 详解Vue.js 技术

    本文主要从8个章节详解vue技术揭秘,小编觉得挺有用的,分享给大家. 为了把 Vue.js 的源码讲明白,课程设计成由浅入深,分为核心.编译.扩展.生态四个方面去讲,并拆成了八个章节,如下: 准备工作 ...

  9. JQ的offset().top与JS的getBoundingClientRect区别详解,JS获取元素距离视窗顶部可变距离

     壹 ❀ 引 我在 JQ的offset().top与js的offsetTop区别详解 这篇博客中详细分析了JQ方法offset().top与JS属性offsetTop的区别,并得出了一条offset( ...

随机推荐

  1. 将Matlab中的矩阵输出到txt文件

    将矩阵输出到txt文件中的方法,遍寻网络,始见真经!!! fid=fopen('C:Documents and Settingscleantotal.ped','wt');%写入文件路径 matrix ...

  2. *HDU1151 二分图

    Air Raid Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  3. MySQL模糊查询

    第一种最土的方法:使用like语句第二种用全文索引 有两种方法,第一种最土的方法:使用like语句第二种听涛哥说用全文索引,就在网上搜一下: 如何在MySQL中获得更好的全文搜索结果 mysql针对这 ...

  4. WPF整理-自定义一个扩展标记(custom markup extension)

    "Markup extensions are used to extend the capabilities of XAML, by providing declarativeoperati ...

  5. iOS一些编译运行问题

    1.在运行工程时,出现错误如下所示: Undefined symbols for architecture x86_64: "_OBJC_CLASS_$_XXXXX", refer ...

  6. Collection

    集合(collection): 使用存储实例的变长的容  容器名    存储的元素类型     长度   数组       基本和引用            定长   集合        引用     ...

  7. MySQL数据的主从复制、半同步复制和主主复制详解

    一.MySQL复制概述 ⑴.MySQL数据的复制的基本介绍 目前MySQL数据库已经占去数据库市场上很大的份额,其一是由于MySQL数据的开源性和高性能,当然还有重要的一条就是免费~不过不知道还能免费 ...

  8. Python3中使用PyMySQL连接Mysql

    Python3中使用PyMySQL连接Mysql 在Python2中连接Mysql数据库用的是MySQLdb,在Python3中连接Mysql数据库用的是PyMySQL,因为MySQLdb不支持Pyt ...

  9. Win7 下安装VirtualBox 没有Ubuntu 64bit 选项问题

    参考: win7安装virtualbox遇到的问题 基于VirtualBox虚拟机安装Ubuntu图文教程 问题 在安装VirtualBox之后,选择虚拟机进行安装的时候发现没有Ubuntu 64bi ...

  10. mockito使用心得

    前提:pom引用<dependency> <groupId>junit</groupId> <artifactId>junit</artifact ...