Board logo

标题: [原创]vbs/bat Hybrid Programming,识货者进 [打印本页]

作者: electronixtar     时间: 2006-12-3 02:29    标题: [原创]vbs/bat Hybrid Programming,识货者进

这个想法我思考了很久。

巧妙利用 bat 和 vbs 的语法特征,让同一个文件,被 cmd.exe 识别成批处理,让 wscrpt.exe 识别成 vbs,并且同时符合两者的语法,并且保证都没有错误,保证两者的高度兼容。经过一个通宵的努力,我实现了这种 bat/vbs 复合编程。


一个 批处理  .vbs 文件,在前面加一段代码(头),就变成了 .bat 批处理,注意,没有生成临时文件,不用修改任何原有代码。

例子:保存下列代码为 test.bat,注意是批处理,但是这个批处理却成功的被 wsh 解析执行了!
CODE:  [Copy to clipboard]
:On Error Resume Next
Sub bat
echo off & cls
echo Batching_codez_here_following_vbs_rules & pause
start wscript -e:vbs "%~f0"
Exit Sub
End Sub
MsgBox "This is vbs"
保存代码为 test.bat,可以看到 echo 出来的东西和 msgbox 出来的消息,呵呵

以上代码只是一个示例,同时执行了 一段 批处理 和 vbs,没有生成临时文件。用了大量的 hack 技巧

下面粗略解释下代码

  Quote:
:On Error Resume Next

cmd.exe 识别成一段注释
wscript.exe 这样识别, : 在vbs语法里代表分行,然后 On Error Resume Next,也就是让WSH忽略一些错误

  Quote:
start wscript -e:vbs "%~f0"

cmd.exe 识别成:启动 wscript.exe ,其参数是:
① -e:vbs  设定以vbs解析文件自身
② "%~f0" 指这个批处理本身。

wscript.exe 把这句识别成:调用一个叫 start 的函数,函数参数是 wscript 这个变量,然后用这个函数的结果来 减去 e。接下来是又是一个 : ,分行,然后又是调用一个名叫 vbs 的函数,参数是字符: "%~f0"

这句是最为精巧的,因为它成功的让 vbs 引擎解释了一段批处理,而且没有错误!当然这些 start()、vbs()函数是不存在的,但是会被 cmd.exe 当成命令执行。为什么不用  wscript //e:vbs "%~f0" 来执行呢?vbs解析会出错的,呵呵

这段代码的核心思想已经介绍完毕了。下面,为了让 批处理 以vbs调用其自身后,马上退出,我们需要 exit 或者 goto :eof,但是 goto call exit 在vbs又是一个关键词,所以我们只能用符合 vbs 语法的 exit sub,所以我们在第二句加一个
sub bat,其实 cmd.exe 寻找了一个叫 sub.exe 的命令,但是这个命令是不存在的,cmd.exe 跳过。然后在 6、7 句加一个 exit sub 以及 end sub,让 批处理结束,同时又符合 vbs 的语法

那个 echo off & cls  ,批处理的意思就是相当于 @echo off ,但是 vbs 不认 @ 符号,所以改成 echo off & cls , vbs 可以解析为,调用一个叫 echo() 的函数,参数为 off & cls ,也就是两个字符串 off 和 cls 相加

Well,接下来,你可以自由地在批处理中书写vbs脚本了,效率和真正的vbs一样高!

这段代码的好处是:不用生成临时文件。其实用 echo 或者 more 或者 find 来生成临时vbs很浪费系统资源的,用我写的这段代码,就完全免去了这些麻烦。直接混合编程,以 start wscript -e:vbs "%~f0" 为界限,上面写 批处理,下面写 vbs,并行不悖!

好了,偶累了,休息去了。大家如果有更好的想法,请回帖,大家一起讨论。

代码以 GPL 发布,也就是说,你用了 est 的代码,你的代码就得给我开源,嘿嘿


================华丽的分割线====================

2006-12-5 新增:支持传递参数的版本:利用了vbs 对 ' 注释敏感的特性
CODE:  [Copy to clipboard]
:On Error Resume Next

:Sub bat
echo off & cls
echo Batching_codez_here_following_vbs_rules & pause >nul
echo '>nul & start "" wscript //e:vbscript "%~f0" %*
Exit Sub : End Sub

MsgBox "This is vbs"
for each i in wscript.arguments
wscript.echo i
next
[ Last edited by electronixtar on 2006-12-6 at 06:13 AM ]
作者: namejm     时间: 2006-12-3 02:36
  强帖留名,沙发~~
作者: vkill     时间: 2006-12-3 02:38
看的晕忽
作者: redtek     时间: 2006-12-3 02:41
狂顶!!!欣赏~~~
作者: 9527     时间: 2006-12-3 02:44
顶,我就知道est早晚会有一番作为的...........est该是出手的时候了........:>
作者: electronixtar     时间: 2006-12-3 02:47
忘记说了,那个   echo off & cls  ,批处理的意思就是相当于 @echo off ,但是 vbs 不认 @ 符号,所以改成 echo off & cls , vbs 可以解析为,调用一个叫 echo() 的函数,参数为 off & cls ,也就是两个字符串 off 和 cls 相加
作者: tao0610     时间: 2006-12-3 03:18
学习一下.
作者: voiL     时间: 2006-12-3 13:23
好东西,慢慢消化一下先.:-)
作者: lxmxn     时间: 2006-12-3 13:37

  很受启发~

作者: redtek     时间: 2006-12-3 13:55
半夜爬起来继续欣赏electronixtar兄大作~:)))
作者: Michael     时间: 2006-12-3 13:59
嗯,喜欢这种精巧的workaround!
作者: ccwan     时间: 2006-12-3 21:03
佩服!给兄加分了,我会好好学习。
作者: qzwqzw     时间: 2006-12-4 05:34
好话不多说了,只说问题吧。

问题在于vbs与bat交错部分太多了,都是从头走到尾,编写一句代码需要考虑两方面的兼容性,否则很容易出问题。

应该尽快让两段流程分离。我试着重写了一个,问题解决了一半,cmd不再管vbs段的闲事了。

但是反之还有很多问题,wsh的脚本检查似乎不理睬wscript.Quit,总是进行全文检查。

这就让bat段的编写变得异常艰难,使用echo ' & 的办法,虽然解决了goto和其他一些特殊字符的问题,但仍然有很多问题。

比如bat段的标签可能与vbs的关键字冲突,从而导致一些问题。

而更复杂的bat段还没有测试,毕竟每句代码都带个“帽子”,太难看了!

主要对wsh和vbs不是很熟,有懂的再想想办法吧。

另外,on error resume next 会限制 vbs 的灵活性,对于要求不能 resume next 的代码段只能再跟一个 on error goto 0 了。

而cls会破坏程序执行前的结果显示,这似乎没办法改变。
CODE:  [Copy to clipboard]
::On Error Resume Next
echo ' > nul & goto bat

vbs:
MsgBox "This is vbs"
Wscript.Quit

:bat
echo ' > nul & @echo off & cls
echo ' > nul & echo Batching_codez_here_following_vbs_rules & pause
echo ' > nul & goto :skip

echo ' > nul & echo 'not echo'

:skip
echo ' > nul & wscript //E:vbs "%~f0"
[ Last edited by qzwqzw on 2006-12-3 at 05:15 PM ]
作者: electronixtar     时间: 2006-12-4 06:27


  Quote:
编写一句代码需要考虑两方面的兼容性,否则很容易出问题。

呵呵,我可是思考了很久,尝试了很多次,可以说是来之不易呢


我当初的目的是,把一个bat变成一个vbs,既然大家还是想在里面大量书写bat,我的想法就是:用 JScript 。因为, JScript 的注释  /* */ 可以跨行。那么我们的批处理只要不出现 */ ,就可以避免被 WSH 解析到。好吧,我改下标题,就叫 bat/vbs/js 混合编程吧,哈哈~~~

btw,楼上的潜水功夫实在了得啊,拜一个

  Quote:
积分 398
发帖 81
注册 2004-3-6
状态 在线

[ Last edited by electronixtar on 2006-12-4 at 06:33 AM ]
作者: qzwqzw     时间: 2006-12-4 06:47
一直都很忙,有空闲也只是看看,真要做起来,太费时间了。

也许vbs中的方法也是存在的——印象中vbs中有跨行的语句,大概是用 & ;或者也许可以构造一个跨行的“字符串”。
作者: electronixtar     时间: 2006-12-5 05:53
现在有个很大的问题了,如何传参数给vbs。郁闷中
作者: NaturalJ0     时间: 2006-12-5 23:35
看的似懂非懂,我也试着写了写。
CODE:  [Copy to clipboard]
:On Error Resume Next
:Sub BAT
echo ' > nul & cls & @echo off
echo ' > nul & setlocal enabledelayedexpansion
echo ' > nul & for /f "skip=8 delims=" %%i in ('type "%~f0"') do (
echo ' > nul & set ##commandline##=%%i
echo ' > nul & set ##commandline##=!##commandline##:~1!
echo ' > nul & !##commandline##!)

':/*// BAT BEGIN
'echo This is BAT.
':*/// BAT END

'call wscript //E:vbs "%~f0"
'GOTO :EOF
:End Sub

':/*// VBS BEGIN
MsgBox "This is VBS."
':*/// VBS END
在中间加 BAT 段时,每行 BAT 命令前都要有个额外的 '
程序先运行 BAT 部分,再运行 VBS 部分。

BAT 部分变量使用时最好全部用 !! 代替 %%
另发现如果 BAT 部分中写上 'pause>nul 就会出问题,还没解决。 o_O

[ Last edited by NaturalJ0 on 2006-12-6 at 12:44 AM ]
作者: redtek     时间: 2006-12-6 00:14
非常精妙!!!

先执行 skip=8 跳过用于 “解释” 之用的 “自身” 代码段,然后再 :~1 去掉左边可以被 VBS “认识” 但不被 VBS 所执行的注释符 “ '  ”,
在 !……!之中执行再执行没有注释的批处理语句。

在这个批处理语句中所向下执行时遇到了去掉 ' 注释符的 “call wscript //E:vbs "%~f0" 语句,于是调用 wscript 来解释 “自己”,
当从头到尾被 wscript 解释时, Sub BAT 与 End Sub 中的 “没有调用者” 的语句被 wscrip “忽略” 不执行,
于是除了 Sub Bat ...End Sub 之间的不被 Wscript “执行” 外,还有 ' 用于注释的语句也不被执行,
最后,就只有一句可以被 wscript 和我们认为是 “有效” 语句:“MsgBox "This is vbs." ” ~:)



欣赏+狂顶~~~

[ Last edited by redtek on 2006-12-5 at 11:25 AM ]
作者: redtek     时间: 2006-12-6 00:34
CODE:  [Copy to clipboard]
'pause >nul
经测试, 'pause 与 >nul 这之间空一个格儿就可以正常执行了~:)
作者: NaturalJ0     时间: 2006-12-6 00:39
我也试过加空格,但加空格后, >nul 的作用没起到。
作者: redtek     时间: 2006-12-6 00:44
可以啦,这样就不会显示什么按任意键的什么提示了~:)
CODE:  [Copy to clipboard]
'cmd /c pause >nul

作者: lxmxn     时间: 2006-12-6 01:21

  强啊,思维的发散啊~顶一个~

作者: NaturalJ0     时间: 2006-12-6 01:27
这方法“耗”掉了一层 CMD 的“解释”,似乎是个很严重的问题啊。 = =b
作者: redtek     时间: 2006-12-6 01:47
经过下面测试,发现显示 “请按任意键继续. . .” 的原因就是下面代码所“反映”出来的!!的特性~:)
CODE:  [Copy to clipboard]
C:\TEMP\vbsbat>set "v=pause >nul"

C:\TEMP\vbsbat>echo !v!
pause >nul

C:\TEMP\vbsbat>!v!
请按任意键继续. . .
所以你上面的 “解释” 代码(!pause >nul!)遇到了这个语句时就出现了上面测试的结果~:)

[ Last edited by redtek on 2006-12-5 at 12:49 PM ]
作者: electronixtar     时间: 2006-12-6 05:37
qzwqzw和NaturalJ0 的代码都很精彩!!!!顶~~~~


好喜欢大家一起讨论的气氛 ^_^
作者: kcdsw     时间: 2006-12-6 22:12
CODE:  [Copy to clipboard]
:On Error Resume Next
Sub bat
echo off & cls
echo Batching_codez_here_following_vbs_rules & pause >nul
start wscript -e:vbs "%~f0"
Exit Sub
End Sub
MsgBox "This is vbs"
CODE:  [Copy to clipboard]
:On Error Resume Next
Sub bat
echo off & cls
echo 中文 & pause >nul
start wscript -e:vbs "%~f0"
Exit Sub
End Sub
MsgBox "This is vbs"
大家看看这2段代码的区别  还有执行时候的区别
作者: kcdsw     时间: 2006-12-6 22:47
NaturalJ0 的代码 很清晰明了

再结合redtek 的 cmd /c 的方法 可以让& > 等符号也正常使用

感叹号 失去效果的时候可以使用 ! 来替代 !!  哈哈

[ Last edited by kcdsw on 2006-12-6 at 10:59 PM ]
作者: kcdsw     时间: 2006-12-6 23:20
CODE:  [Copy to clipboard]
:On Error Resume Next
:Sub BAT
echo ' > nul & cls & @echo off & setlocal enabledelayedexpansion & set file=%0
echo ' > nul & for /f "skip=7 delims=" %%i in ('type "%~f0"') do (
echo ' > nul & set ##commandline##=%%i
echo ' > nul & set ##commandline##=!##commandline##:~1!
echo ' > nul & !##commandline##! )

':BAT BEGIN
'cmd /c echo 按任意键开始执行VBS代码! & pause >nul &cls
':BAT END

'cmd /c start wscript //E:vbs %file%
'exit
:End Sub

'VBS BEGIN
MsgBox "This is VBS."
'VBS END
bat执行完毕后 退出

[ Last edited by kcdsw on 2006-12-7 at 12:29 AM ]
作者: 0401     时间: 2006-12-7 06:11
原来 electronixtar 就是 est 啊。。。

留个名,大家继续热烈地讨论,我等下回来学习。。
作者: electronixtar     时间: 2006-12-7 06:30


  Quote:
原来 electronixtar 就是 est 啊。。。

寒~~~
作者: asbai     时间: 2006-12-7 12:16


  Quote:
Originally posted by qzwqzw at 2006-12-4 06:47:
一直都很忙,有空闲也只是看看,真要做起来,太费时间了。

也许vbs中的方法也是存在的——印象中vbs中有跨行的语句,大概是用 & ;或者也许堮..

有道理,如果 vbs 支持多行字符串或多行注释之类的语法就很容易了。:)
作者: electronixtar     时间: 2006-12-8 00:30
asbai也很难得上线呀,哈哈
作者: youxi01     时间: 2006-12-8 06:40
既然可以利用::(CMD中为注释)的特性,那我们其实不用专门构造两者都可以识别的函数(或标签)这么麻烦了!

凡是属于vbs的代码,前面全部加::(CMD中为注释语句,而vbs会忽略[好象是换行的标记],只执行::后面的内容),而属于CMD的命令则在前面加echo '>nul && CMD命令.....

测试代码:
CODE:  [Copy to clipboard]
::On Error Resume Next
echo '>nul & cls & @ echo off& echo ok &start wscript -e:vbs "%~f0"  & pause
::test()
::function test()
::     msgbox "ok!"
::end function
不过这种方法有个不好的地方就是,对于CMD中的for命令来说有点痛苦,因为只能将for中的所以语句写在一行里面(或者不停的echo '>nul)。

[ Last edited by youxi01 on 2006-12-8 at 07:09 AM ]
作者: redtek     时间: 2006-12-8 07:04
欣赏~~精彩的内容越来越多了,顶起来~~
作者: youxi01     时间: 2006-12-8 07:19
至于利用20F的代码,对于普通的命令,比如echo 等确实很好,但是对于for循环好象却显示 “for不是内部外部命令"
作者: youxi01     时间: 2006-12-8 07:56
通用文件中for命令的解决方案之一:
CODE:  [Copy to clipboard]
::'以下的内容可以看成是vbs和CMD通用文件的通用文件头(固定不变)。
::On Error Resume Next
echo ' > nul & cls & @echo off
echo ' > nul & setlocal enabledelayedexpansion
echo ' > nul & for /f "skip=10 delims=# tokens=2" %%i in (%~0) do (
echo ' > nul & set cmdline=%%i
echo ' > nul & !cmdline!)

::'下面的内容为命令行内容,格式为CMD的书写格式,但前面需要添加'#(#为分隔符)
::'for、if语句有点特殊,需要使用cmd来调用,否则则被当成普通命令for会导致错误!
'#echo ok!
'#cmd /c for /l %i in (1 1 10) do @echo %i
'#call wscript //E:vbs "%~f0"
'#pause

::'下面的内容为vbs文件内容,格式为vbs的书写格式,但前面需要添加::

::test()
::function test()
::     msgbox "ok!"
::end function
有关在代码中书写标签的问题还有待解决!!~

[ Last edited by youxi01 on 2006-12-8 at 08:13 AM ]
作者: fastslz     时间: 2006-12-8 09:34
忙里偷闲~
est强贴还是要顶的~
作者: electronixtar     时间: 2006-12-8 10:42
谢谢赏光!
作者: youxi01     时间: 2006-12-8 13:57
不生成临时文件,查询自定义天数前后的日期:
CODE:  [Copy to clipboard]
::On Error Resume Next
echo ' > nul & cls & @echo off
echo ' > nul & setlocal enabledelayedexpansion
echo ' > nul & for /f "skip=7 delims=# tokens=2" %%i in (%~0) do (
echo ' > nul & set cmdline=%%i
echo ' > nul & !cmdline!)

'#title 查询若干天前后的日期
'#echo.
'#set /p test=请输入天数(请输入整数):
'#call cscript //e:vbs "%~f0" "!test!" //nologo
'#pause

::'下面的内容为vbs文件内容,格式为vbs的书写格式,但前面需要添加::
::param=wscript.arguments(0)
::wscript.echo vbcrlf
::if (isnumeric(param)) then
::   if param=<0 then
::      wscript.echo -param&"天前的日期为:"&dateadd("d",param,Date)
::   else
::      wscript.echo param&"天后的日期为:"&dateadd("d",param,Date)
::   end if
::else
::      wscript.echo "请输入数字!"
::end if
::wscript.echo vbcrlf
问题:通用文件目前仍不能很好的支持标签

[ Last edited by youxi01 on 2006-12-9 at 12:11 AM ]
作者: youxi01     时间: 2006-12-8 14:10
看样子,要在通用文件中加入标签,只好构造特殊‘函数’(能适合vbs和CMD)才能解决了
作者: kennyfan     时间: 2006-12-8 23:50
可能本人理解能力有限暂不明白!先收下代码 慢慢研究!
作者: qzwqzw     时间: 2006-12-9 08:18
后来几位的for解析方案可谓得不偿失,解决了部分问题,但却带来了更多问题。

至于标签的冲突问题,可以在我的方案中的标签名中加入'的前缀解决,如下。

另外,echo '>nul& 的帽子很有改变的必要,但目前有以下问题没有解决:

1、vbs中如何实现goto调转;

2、vbs中的分号和百分号分别有什么特定的语法意义或用途;

3、vbs的多行注释通过什么方法可以实现;
CODE:  [Copy to clipboard]
::On Error Resume Next
echo '>nul& goto bat

vbs:
MsgBox "This is vbs"
Wscript.Quit

:bat
echo '>nul& @echo off & cls
echo '>nul& echo Batching_codez_here_following_vbs_rules & pause
echo '>nul& goto :'set

echo '>nul& echo -not echo-

:'set
echo '>nul& wscript //E:vbs "%~f0"
[ Last edited by qzwqzw on 2006-12-8 at 07:40 PM ]
作者: electronixtar     时间: 2006-12-9 09:47


  Quote:
1、vbs中如何实现goto调转;

拒我所知,vbs不支持goto

  Quote:
2、vbs中的分号和百分号分别有什么特定的语法意义或用途;

分号没有定义,百分号是 取余数吧,忘记了

  Quote:
3、vbs的多行注释通过什么方法可以实现;

没法实现。嘿嘿
作者: youxi01     时间: 2006-12-9 11:25


  Quote:
Originally posted by qzwqzw at 2006-12-9 08:18 AM:
后来几位的for解析方案可谓得不偿失,解决了部分问题,但却带来了更多问题。

采用这种方法的原因是:避免大量的垃圾代码echo '>nul,至于用for读取文件本身只是在处理">"符号的时候会出现部分问题!至于for if语句的问题已解决。

至于标签冲突的问题,偶然发现,只要不取与vbs中的函数同名就行了,其它的vbs中好象也会忽略:
测试代码:
CODE:  [Copy to clipboard]
::On Error Resume Next

::'CMD代码
:test1
   echo '>nul& @echo off & cls
   echo '>nul& echo ok!
   echo '>nul& goto :test2
:test2
   echo '>nul& wscript //E:vbs "%~f0"

::'vbs代码:
::msgbox "ok!"

作者: qzwqzw     时间: 2006-12-9 23:27


  Quote:
Originally posted by youxi01 at 2006-12-8 22:25:
采用这种方法的原因是:避免大量的垃圾代码echo '>nul,至于用for读取文件本身只是在处理">"符号的时候会出现部分问题!至于for if语句 ...

这就是你我看待问题的角度不同了。

我认为echo '>nul & 的帽子虽然垃圾,很有替换的必要,但是它至少保持了后面批处理代码的原貌。

而你想着for解析虽然使有些代码做出变化,但是它简化了语句的编写。

我申明我的观点:不应为代码的简洁性,而牺牲代码的健壮性。

因为使用for解析批代码并执行,不仅仅有for和if的问题,也存在其它许多兼容性的问题。

for/f本身是一个功能弱化的命令解释器,在对脚本的解释机理上与cmd有许多不同。

有些是已知的,比如for\if这些命令以及许多已探测到的非常态字符,而很多是未知的。

总的来说,即使利用for来代替type实现文本输出,仍然存在很多障碍,更何况是进行命令解析了。

如果谁能确定自己所编写的for解析脚本可以完全和type命令一致,那么我就相信用for进行命令解析是可行的。

另外,我有一个编写代码的原则:尽量不让其它的语句来影响正在编写的语句,也就是说要尽量保持语句、模块、代码之间的独立性。

我说的将vbs与bat流程尽快分开,正是基于这一原则。

可以这样设想,如果采用for解析的方案,那么我在写到for/if语句时必须去注意更换代码的写法。

这既消耗了我的精力,也消耗了代码阅读者的精力。

所以说,如果在夹杂着垃圾的代码和夹杂着利刃的代码之间必须做个选择,那么我会选择前者。
-------------------------

另外,关于标签的冲突问题,早前就已经知道是部分标签与vbs函数冲突,但是这仍然是问题。

因为我编写代码时,往往忽略了Bat的某个标签正是vbs的关键字。

如果不加上 ' 帽子,可能会使代码的调试走许多弯路。

而且如果去掉:: On error goto next ,你会发现并不是很少冲突,而是很多冲突都被强制丢弃了。

--------------------------

关于我上次提到的三个问题,大概也知道是有些不切实际的。

实际上这所有的努力,只是为了实现使wsh直接跳过对bat段代码的解析。

否则将仍不可避免一些兼容性问题的存在。

[ Last edited by qzwqzw on 2006-12-9 at 10:39 AM ]
作者: asbai     时间: 2006-12-10 07:09


  Quote:
Originally posted by electronixtar at 2006-12-8 00:30:
asbai也很难得上线呀,哈哈

呵呵,其实我经常过来潜潜水的。无奈各位老大讨论的话题过于精深了,平时也插不上什么话的说~
作者: electronixtar     时间: 2006-12-10 09:37
什么时候我还是写一个js的bat吧,js支持跨行注释
作者: jmz573515     时间: 2006-12-25 21:38
好东西,学习.
作者: scriptor     时间: 2006-12-26 02:54
恩满好的
又长进了
作者: gene771771     时间: 2006-12-26 13:52
看不懂。。。但是还是顶~~~~~~~~
作者: chainliq     时间: 2006-12-26 18:11
靠,这样贴子要狂顶OY`````````
作者: scriptor     时间: 2007-1-19 05:13


  Quote:
Originally posted by electronixtar at 2006-12-2 13:29:
这个想法我思考了很久。

巧妙利用 bat 和 vbs 的语法特征,让同一个文件,被 cmd.exe 识别成批处理,让 wscrpt.exe 识别成 vbs,并且同时符 ...



我也有过的想法,只是不知道怎么做。哎。。。

相见恨晚哪!...

给加分!



[ Last edited by scriptor on 2007-1-18 at 04:14 PM ]
作者: vlq5299     时间: 2007-1-19 06:19
xuexi^^^^
作者: qzwqzw     时间: 2007-5-27 14:20    标题: Perl和CMD脚本的混杂编写示例

偶然从XP安装盘里发现这么一个脚本

主要作用是

  Quote:
prevent fatal page fault when using Win9x and running winnt32.exe from a network share

关键代码就是这头三行:
CODE:  [Copy to clipboard]
@rem = '
@goto endofperl
';
可惜这个脚本是无法运行的

因为它是从远程主机上读取Perl解释器

所以想要运行它需要修改perl变量值

当然,运行它之前还应该想清楚它会对你的系统造成什么影响

反正我是没有运行过的 :)
CODE:  [Copy to clipboard]
@rem = '
@goto endofperl
';
#+---------------------------------------------------------------------------
#
#  File:       R U N W 3 2 . B A T
#
#  Contents:   Perl/cmd script to prevent fatal page fault when using Win9x
#                 and running winnt32.exe from a network share.
#
#  Author:     kumarp 21-August-98
#
#  Notes:  
#    Windows95 does not allow an executable on a network share to be copied
# to pagefile before executing it, it simply runs it directly
# from the network share. In case of a network problem, this results
# in a fatal pagefault error.
#
#   This script is written with the aim to avoid this problem when
# running winnt32.exe from the ntbuilds release shares. It simply
# copies all winnt32.exe files (~ 4MB) to a temporary directory on the
# local hard drive. It does not copy the entire release share to your
# hard drive. It then launches winnt32.exe from the local hard drive.
#
#----------------------------------------------------------------------------

my $usage_help = "Usage:  runw32.bat [any option valid for winn32.exe]";

if ($ARGV[0] =~ /[-\/]([hH?]|(help))/i)
{
    print $usage_help;
    exit;
}

if (rindex($0, '\\') >= 0)
{
    $curdir = substr($0, 0, rindex($0, '\\'));
}
else
{
    $curdir = `cd`;
}

chomp($curdir);

$tempDir = $ENV{"TEMP"};
$winnt32_src = $curdir;
$winnt32_dst = "$tempDir\\winnt32";
print "Please wait while files are being copied from $winnt32_src to $winnt32_dst...\n";
`xcopy /q/s/d $winnt32_src\\*.* $winnt32_dst`;
die "...error copying files from $winnt32_src: $!\n" if ($? != 0);

$nt5_src=$curdir;
if ($nt5_src =~ /(.+)winnt32$/i)
{
    $nt5_src = $1;
}

$cmdline = "$winnt32_dst\\winnt32.exe /s:$nt5_src " . join(" ", @ARGV);
print "$cmdline\n";
`$cmdline`;
#`rd /s/q $winnt32_dst`;
#`deltree /y $winnt32_dst`;
__END__
:endofperl
@echo off

set THISFILE=%0
if not exist %THISFILE% set THISFILE=%0.bat

if "%TEMP%"=="" goto not_set_temp
if "%TMP%"=="" goto not_set_temp
set ARGS=
:loop
if .%1==. goto endloop
set ARGS=%ARGS% %1
shift
goto loop
:endloop

set WINNT32_DIR=%TEMP%\winnt32
if not exist %WINNT32_DIR% md %WINNT32_DIR%

rem Need to find a good location for perl.exe

set PERL=\\kumarp1\public\perl\perl.exe
if not exist %PERL% set PERL=\\scratch\scratch\kumarp\perl\perl.exe
if not exist %PERL% goto perl_not_found

%PERL% %THISFILE% %ARGS%

goto the_end

:perl_not_found
echo Cannot load %PERL%
goto the_end

:not_set_temp
echo Environment variable TEMP or TMP is not set
goto the_end

:the_end
-------------------

本来是想编写wiki的
http://www.cn-dos.net/mediawiki/index.php?title=Hybird

可惜IP被封锁

看谁觉得有用吧

[ Last edited by qzwqzw on 2007-5-27 at 02:21 PM ]
作者: vkill     时间: 2007-5-27 17:52
@rem = '
@goto endofperl
';


这三行什么意思那?
作者: qzwqzw     时间: 2007-5-27 18:04
批处理解释时

第一行为注释,并取消rem的命令行回显,因为它前面没有@ECHO OFF

第二行跳转到 Perl 脚本之后,也就是bat脚本开始的地方

第三行因为不会执行而被忽略

Perl解释时

定义一个名为 @rem ,值为@goto endfperl 的变量

然后接着执行以下的perl 脚本

__END__是perl脚本的结束标志
(真希望wsh也有这样的结束标志)

:endofperl 是bat脚本的开始标签
作者: lxmxn     时间: 2007-5-28 02:10
虽然不懂perl,还是支持一下!
作者: lotus516     时间: 2007-5-28 13:06
这么好的贴才看到!!
作者: vkill     时间: 2007-12-7 15:48    标题: ruby和CMD脚本的混杂编写示例

....
作者: AlexZhang     时间: 2007-12-7 21:57
不错
以后再bat里面...我直接写vb咯~
作者: jmz573515     时间: 2007-12-9 21:24
今天重新看了一下,才有点明白是怎么回事儿...
CODE:  [Copy to clipboard]
::On Error Resume Next
echo '>nul &cls& @echo off&wscript -e:vbs "%~f0"
::wscript.sleep 5000
echo '>nul & echo 5妙延时完毕!& pause&exit
::if right(wscript.scriptname,3)="vbs" then msgbox "5妙延时完毕!"





欢迎光临 中国DOS联盟论坛 (http://cndos.fam.cx/forum/) Powered by Discuz! 2.5