[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[其他] [研究]新一代外部命令?VBS强化批处理?

给出代码一则:
  1. @echo off
  2. set /p a=Type:
  3. set "a=%a:"=""%"
  4. setlocal enabledelayedexpansion
  5. echo wscript.echo len("!a!")>a.vbs
  6. for /f %%a in ('cscript /nologo a.vbs') do set alength=%%a
  7. del /f /q a.vbs
  8. echo 长度为%alength%
  9. pause
复制代码
好了,这个例子给出的结果还比较理想:没有臃肿的代码,核心部分不到5行,强大乎~




当然,这个不是我最先提出来的。。。

这里是运用了VBS中的WScript.Echo方法,就是向脚本宿主发送消息。。。

当直接双击运行VBS的时候,脚本宿主是WScript,但是在CMD中用CScript来调用的话脚本宿主就是CMD了,实现了结果的输出。。。

那么接下来就只需要通过For,读取结果并赋值就可以了。。。
  1. 创建VBS —> VBS计算结果 —> VBS返回结果 —> 通过For获取结果 —> 删除VBS
复制代码
当然,可行性不高。每次都这样做的话,也算是很麻烦的,代码也变长很多,临时文件多。。。



改造方案一:Mshta调用

这样做的最大好处是,没有临时文件,无论怎么做都可以,只要在一行只内,是很理想的方案。。。
  1. mshta vbscript:WScript.Echo(Len("123"))(window.close)
复制代码
很可惜的是,执行失败,提示缺少WScript对象。。。

分析下原因:

缺少WScript对象,就是没有脚本宿主,怎么听都像扯谈,既然都能执行了,怎么会没有脚本宿主呢?

其实我们看看命令本身,我们就会知道答案:mshta?!

没看出来?正常,因为这个命令是缩写,但是这样写你就能看出来:MS-HTA!!

对,实际上,我们所编写的VBS代码都是在一个HTA上面运行的,HTA实际上就是一个网页。。。

是网页调用脚本,并不是脚本被脚本宿主解析并执行!

所以,mshta调用是没有脚本宿主的。。。

方案一无效。。。



改造方案二:外部命令化

我们常用的内部命令,外部命令,不外乎都是EXE和COM,能实现一定的功能,多为高级语言所编写。。。

借助命令的思想,可以把编写好的VBS作为一个外部的命令。。。

例子一个:

Example.vbs
  1. @Echo Off
  2. SetLocal EnableDelayedExpansion
  3. Set /p a=Type:
  4. Call :Functions "aLength" "StrLen" "!a!"
  5. Call :Functions "pButton" "MsgBox" "字串符!a!的长度为!aLength!" "64" "CMD"
  6. Call :Functions "pButton" "MsgBox" "继续测试?" "68" "CMD"
  7. If %pButton%==6 (%0) else (Goto :EOF)
  8. :Functions
  9. Setlocal EnableExtensions
  10. For /f "tokens=1*" %%a in (""%*"") Do (For /f %%d in ('CScript /NoLogo Functions.vbs %%b') Do (set ret=%%d))
  11. Endlocal&Set "%~1=%ret%"
  12. Goto :EOF
复制代码
Functions.vbs
  1. Set objArgs = WScript.Arguments
  2. If objArgs.Count<=0 Then WScript.quit
  3. Select Case objArgs(0)
  4. Case "StrLen"
  5. If objArgs.Count<2 Then WScript.quit
  6. WScript.Echo Len(objArgs(1))
  7. Case "MsgBox"
  8. If objArgs.Count<4 Then WScript.quit
  9. WScript.Echo MsgBox(objArgs(1),objArgs(2),objArgs(3))
  10. End Select
复制代码
测试效果很好。。。

可能有人会说,获取长度的话,完全可以自己写一个,消息框的话完全可以用mshta代替。。。

但是,这样虽然多了一个VBS文件,但是可拓充性很强。。。

如果你想获得一个字符的ASCII码值呢?如果你想实现浮点运算呢?如果你想小数开方、自然对数等等呢?

这样做,你完全可以马上写出来一个自己需要的伪劣“第三方命令行工具”!

至于消息框,用mshta你是不可能知道用户按下了哪个按钮,而这样做完全可以。。。




说说方案二的缺点:

测试环境:Window Vista Home Basic

在测试环境下,执行前需要花费0.3秒左右,能感受到明显的停顿,这是VBS的问题,启动慢

其次,并不能保证每台机器都有装上VBS,还是有部分用户没有装VBS的

第三,在VBS执行期间会增加两个进程(cmd.exe和cscript.exe),可以用任务管理器杀掉,导致返回值为空,或出错退出

第四,VBS损坏等直接导致执行失败,同命令行工具一样,少一个批处理都无法完成任务



好了,这个所谓的命令行工具,前途还是有的。。。

[ 本帖最后由 defanive 于 2009-2-22 17:14 编辑 ]

自写VBS第三方工具

自己写的一个VBS,里面有很多功能

功能:


StrLen:字符串长度
MsgBox:多样式消息框
InputBox:输入框
Math:Set /a 的拓展,支持输入任意表达式,表达式中可使用数学函数(Abs等)
DataAdd:为给定日期推移任意单位时间
DataDiff:计算两个日期单位时间差
GetLocale:获得当前区域ID
VBSFunction:执行VBS命令并返回值
VBScript:执行VBS命令但不返回值

当然,功能还可以拓展,不过我觉得没有必要了,有了VBScript和VBSFunction就可以实现调用VBS了。。。

使用方法:

将Functions.vbs放到批处理同一目录下,在批处理最后增加函数代码(见下文)

然后随时需要调用VBS中的函数就这样:


Call :Functions "储存返回结果的变量" "函数名" "参数一" "参数二" "参数三" ……

例如,调用StrLen函数则这样写:

Call :Functions "aRes" "StrLen" "%a%"

则变量a内容的长度就被保存在了aRes变量里面

VBS和示例批处理在附件下载:




Functions.vbs
  1. Set objArgs = WScript.Arguments
  2. If objArgs.Count<=0 Then WScript.quit
  3. Select Case objArgs(0)
  4. Case "StrLen"
  5. If objArgs.Count<2 Then WScript.quit
  6. WScript.Echo Len(objArgs(1))
  7. Case "MsgBox"
  8. If objArgs.Count<4 Then WScript.quit
  9. WScript.Echo MsgBox(objArgs(1),objArgs(2),objArgs(3))
  10. Case "Math"
  11. If objArgs.Count<2 Then WScript.quit
  12. WScript.Echo CDbl(Eval(objArgs(1)))
  13. Case "InputBox"
  14. If objArgs.Count<4 Then WScript.quit
  15. WScript.Echo InputBox(objArgs(1),objArgs(2),objArgs(3))
  16. Case "DateAdd"
  17. If objArgs.Count<4 Then WScript.quit
  18. WScript.Echo DateAdd(objArgs(1),objArgs(2),objArgs(3))
  19. Case "DateDiff"
  20. If objArgs.Count<4 Then WScript.quit
  21. WScript.Echo DateDiff(objArgs(1),objArgs(2),objArgs(3))
  22. Case "GetLocale"
  23. WScript.Echo GetLocale()
  24. Case "VBSFunction"
  25. If objArgs.Count<2 Then WScript.quit
  26. WScript.Echo Eval(objArgs(1))
  27. Case "VBScript"
  28. If objArgs.Count<2 Then WScript.quit
  29. Execute(objArgs(1))
  30. End Select
复制代码
使用这个VBS需要在批处理尾部加上函数代码:
  1. Goto :EOF
  2. :Functions
  3. Setlocal EnableExtensions
  4. For /f "tokens=1*" %%a in (""%*"") Do (For /f %%d in ('CScript /NoLogo Functions.vbs %%b') Do (set "ret=%%d"))
  5. Endlocal&Set "%~1=%ret%"
  6. Goto :EOF
复制代码

TOP

一般只要支持VBS的系统安装时都会安装,但是部分精简版,或者某些无聊人士会手动把VBS的解释关联给取消掉。。。

TOP

7L,WSH的确不需要安装,但是用户可以破坏CScript.exe和WScript.exe,或者没有注册vbsXXXX.dll

TOP

VBS是很强大的。。。

TOP

返回列表