标题: [其他] [研究]新一代外部命令?VBS强化批处理? [打印本页]
作者: defanive 时间: 2009-2-21 21:28 标题: [研究]新一代外部命令?VBS强化批处理?
给出代码一则:- @echo off
- set /p a=Type:
- set "a=%a:"=""%"
- setlocal enabledelayedexpansion
- echo wscript.echo len("!a!")>a.vbs
- for /f %%a in ('cscript /nologo a.vbs') do set alength=%%a
- del /f /q a.vbs
- echo 长度为%alength%
- pause
复制代码
好了,这个例子给出的结果还比较理想:没有臃肿的代码,核心部分不到5行,强大乎~
当然,这个不是我最先提出来的。。。
这里是运用了VBS中的WScript.Echo方法,就是向脚本宿主发送消息。。。
当直接双击运行VBS的时候,脚本宿主是WScript,但是在CMD中用CScript来调用的话脚本宿主就是CMD了,实现了结果的输出。。。
那么接下来就只需要通过For,读取结果并赋值就可以了。。。- 创建VBS —> VBS计算结果 —> VBS返回结果 —> 通过For获取结果 —> 删除VBS
复制代码
当然,可行性不高。每次都这样做的话,也算是很麻烦的,代码也变长很多,临时文件多。。。
改造方案一:Mshta调用
这样做的最大好处是,没有临时文件,无论怎么做都可以,只要在一行只内,是很理想的方案。。。- mshta vbscript:WScript.Echo(Len("123"))(window.close)
复制代码
很可惜的是,执行失败,提示缺少WScript对象。。。
分析下原因:
缺少WScript对象,就是没有脚本宿主,怎么听都像扯谈,既然都能执行了,怎么会没有脚本宿主呢?
其实我们看看命令本身,我们就会知道答案:mshta?!
没看出来?正常,因为这个命令是缩写,但是这样写你就能看出来:MS-HTA!!
对,实际上,我们所编写的VBS代码都是在一个HTA上面运行的,HTA实际上就是一个网页。。。
是网页调用脚本,并不是脚本被脚本宿主解析并执行!
所以,mshta调用是没有脚本宿主的。。。
方案一无效。。。
改造方案二:外部命令化
我们常用的内部命令,外部命令,不外乎都是EXE和COM,能实现一定的功能,多为高级语言所编写。。。
借助命令的思想,可以把编写好的VBS作为一个外部的命令。。。
例子一个:
Example.vbs- @Echo Off
- SetLocal EnableDelayedExpansion
- Set /p a=Type:
- Call :Functions "aLength" "StrLen" "!a!"
- Call :Functions "pButton" "MsgBox" "字串符!a!的长度为!aLength!" "64" "CMD"
- Call :Functions "pButton" "MsgBox" "继续测试?" "68" "CMD"
- If %pButton%==6 (%0) else (Goto :EOF)
- :Functions
- Setlocal EnableExtensions
- For /f "tokens=1*" %%a in (""%*"") Do (For /f %%d in ('CScript /NoLogo Functions.vbs %%b') Do (set ret=%%d))
- Endlocal&Set "%~1=%ret%"
- Goto :EOF
复制代码
Functions.vbs- Set objArgs = WScript.Arguments
- If objArgs.Count<=0 Then WScript.quit
- Select Case objArgs(0)
- Case "StrLen"
- If objArgs.Count<2 Then WScript.quit
- WScript.Echo Len(objArgs(1))
- Case "MsgBox"
- If objArgs.Count<4 Then WScript.quit
- WScript.Echo MsgBox(objArgs(1),objArgs(2),objArgs(3))
- 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 编辑 ]
作者: defanive 时间: 2009-2-21 21:29 标题: 自写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- Set objArgs = WScript.Arguments
- If objArgs.Count<=0 Then WScript.quit
- Select Case objArgs(0)
- Case "StrLen"
- If objArgs.Count<2 Then WScript.quit
- WScript.Echo Len(objArgs(1))
- Case "MsgBox"
- If objArgs.Count<4 Then WScript.quit
- WScript.Echo MsgBox(objArgs(1),objArgs(2),objArgs(3))
- Case "Math"
- If objArgs.Count<2 Then WScript.quit
- WScript.Echo CDbl(Eval(objArgs(1)))
- Case "InputBox"
- If objArgs.Count<4 Then WScript.quit
- WScript.Echo InputBox(objArgs(1),objArgs(2),objArgs(3))
- Case "DateAdd"
- If objArgs.Count<4 Then WScript.quit
- WScript.Echo DateAdd(objArgs(1),objArgs(2),objArgs(3))
- Case "DateDiff"
- If objArgs.Count<4 Then WScript.quit
- WScript.Echo DateDiff(objArgs(1),objArgs(2),objArgs(3))
- Case "GetLocale"
- WScript.Echo GetLocale()
- Case "VBSFunction"
- If objArgs.Count<2 Then WScript.quit
- WScript.Echo Eval(objArgs(1))
- Case "VBScript"
- If objArgs.Count<2 Then WScript.quit
- Execute(objArgs(1))
- End Select
复制代码
使用这个VBS需要在批处理尾部加上函数代码:- Goto :EOF
- :Functions
- Setlocal EnableExtensions
- For /f "tokens=1*" %%a in (""%*"") Do (For /f %%d in ('CScript /NoLogo Functions.vbs %%b') Do (set "ret=%%d"))
- Endlocal&Set "%~1=%ret%"
- Goto :EOF
复制代码
作者: Batcher 时间: 2009-2-21 22:37
其次,并不能保证每台机器都有装上VBS,还是有部分用户没有装VBS的
能否举个例说明一下哪些系统没有装VBS呢?
作者: defanive 时间: 2009-2-21 22:47
一般只要支持VBS的系统安装时都会安装,但是部分精简版,或者某些无聊人士会手动把VBS的解释关联给取消掉。。。
作者: BBCC 时间: 2009-2-21 23:33
的确如此,通过VBS来做成 bat难以完成的东西会是很方便.
但好像方案2的例子报错的说...
F:\Test>F:\Test\example.bat
Type:153
F:\Test\Functions.vbs(1, 1) Microsoft VBScript compilation error: Invalid charac
ter
F:\Test\Functions.vbs(1, 1) Microsoft VBScript compilation error: Invalid charac
ter
此时不应有 &。
另外有点小笔误.
作者: everest79 时间: 2009-2-22 01:17
脚本是解释性语言,可以这么理解,在常规的windows桌面环境下,它的解释器是WSH,也就是windows 脚本宿主,如果在IE中执行,那他的解释器就是IE,在MSHTA中执行,那么解释器就是MSHTA
而WScript对象,是属于WSH,并不是一个VBScript自带的内部对象所以不能在其它解释器中直接使用
WSH是windows系统自带的一个功能,不存在安装的问题
作者: defanive 时间: 2009-2-22 17:41
7L,WSH的确不需要安装,但是用户可以破坏CScript.exe和WScript.exe,或者没有注册vbsXXXX.dll
作者: zqz0012005 时间: 2009-2-22 18:39
这个标题起得,那个啥。。。
早已不是“新一代”了,只是玩bat的很多,而玩vbs的较少,vbs的应用往往没有bat广。而实际上对于bat难以解决的或不方便解决的,高手往往会借助于vbs。
如果在网吧上网,我一般会运行一下- regsvr32 /s wshom.ocx scrrun.dll vbscript.dll jscript.dll
复制代码
作者: Batcher 时间: 2009-2-22 18:42 标题: 回复 9楼 的帖子
其实在实际工作中,VBS的用处也挺多的。
我做过的项目中有用VBS监控硬盘空间变化并自动发邮件的,还有监控网络状态的等等。
作者: defanive 时间: 2009-2-27 18:10
VBS是很强大的。。。
作者: youxi01 时间: 2009-3-29 12:12
想法非常不错
不过个人建议:我们需要去开发那些批处理不能完成或者不好完成的vbs功能块,如:日期计算、字符串长度计算等。
而且要么就不做,要做就做好,应该给一些各“命令”使用说明....
作者: ejzhang 时间: 2010-8-2 12:36
在服务器端完全可以用VBS的,因为服务器端的环境都比较可控,能保证VBS的正常运行,而且VBS要比BAT强大得多。
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |