饮歌长啸
我以前认为答案是否定的。但是DosTips用户Liviu发现<SUB>字符(Ctrl-Z,0x1A,十进制26)在批处理文件中嵌入时会产生双值效应。如果功能有点像行结束符,那么在REM之后的批处理命令(或:cripthack)如果前面有Ctrl-Z,就有可能执行这些命令。http:/www.dostips.com/Forum/viewtopic.php?P=13160#p 13160这一点已经在XP家庭版SP3,Vista家庭高级sp 2 64位和Vista Enterprisesp2 32位上得到确认。我假设它适用于其他Windows版本。注 - 下面的代码应该嵌入了Ctrl-Z字符。我发誓,当我看到IE8的时候,我经常在这个网站上看到他们。但是他们似乎已经从这个帖子中消失了,我想不出怎么再发了。我用字符串替换了字符<SUB>::<sub>echo This will execute in batch, but it will fail as vbs.rem<SUB>echo This will execute in batch, and it is also a valid vbs comment::'<SUB>echo This will execute in batch and it is also a valid vbs comment这是一个成功的批/VBS混合的关键。只要每个批处理命令前面有rem<SUB>或::'<SUB>,则VBS引擎将看不到它,但批处理命令将运行。只需确保将批处理部分终止为EXIT或EXIT /B..然后脚本的其余部分可以是普通的VBS。如果需要的话,你甚至可以有一个批次标签。:'Label既是一个有效的VBS注释,也是一个有效的批处理标签。下面是一个简单的混合脚本。(再次与<SUB>取代嵌入式Ctrl-Z字符)::'<SUB>@cscript //nologo //e:vbscript "%~f0" & exit /bWScript.Echo "Example of a hybrid VBS / batch file"更新2012-04-15Jeb找到了一种解决方案,可以避免尴尬的CTRL-Z,但它在开始时输出回波,并设置一些无关的变量。我找到了一个没有CTRL-Z的解决方案,它消除了无关变量,而且更容易理解。正常情况下,特殊人物&, |, <, >等不起作用之后REM语句批处理。但是这些特殊的角色REM...我在http:/www.dostips.com/Forum/viewtopic.php?P=3500#P 3500..测试表明REM.仍然是VBS的有效评论。编辑 -根据Jeb的评论,使用起来更安全REM^(插入符号后面有一个空格)。下面是一个简单的VBS/批处理混合使用REM^ &..唯一的缺点是指纹REM &一开始,杰布的解决方案ECHO OFF.rem^ &@cscript //nologo //e:vbscript "%~f0" & exit /bWScript.Echo "Example of a hybrid VBS / batch file"下面是另一个简单的示例,它演示了多个批处理命令,包括对标记子例程的调用。::' VBS/Batch Hybrid::' --- Batch portion ---------rem^ &@echo offrem^ &call :'subrem^ &exit /b:'subrem^ &echo begin batchrem^ &cscript //nologo //e:vbscript "%~f0"rem^ &echo end batchrem^ &exit /b'----- VBS portion ------------wscript.echo "begin VBS"wscript.echo "end VBS"'wscript.quit(0)我仍然喜欢CTRL-Z解决方案,因为它消除了所有无关的输出。更新2012-12-17TomLavedas发布了一种方法,可以方便地从GoogleGroups的批处理脚本中运行动态VBS:无文件VBS混合脚本..该方法使用mshta.exe(MicrosoftHTML应用程序主机)。他最初的批处理解决方案依赖于一个外部的小型VBS.BAT脚本来执行一个for/F中的VBS。我稍微修改了语法,以便于直接嵌入到任何给定的批处理脚本中。它很慢,但很方便。它仅限于执行VBS的一行。VBS是正常编写的,但所有引号必须加倍:包含字符串的引号必须写为"",并且字符串内部的引号必须写为""""..通常,Mini脚本是在for/F的IN()子句中执行的,它可以直接执行,但只有在stdout被重定向或管道化时才能执行。只要安装了IE,它就可以从XP开始在任何Windows操作系统上工作。@echo off
setlocal:: Define simple batch "macros" to implement VBS within batchset "vbsBegin=mshta vbscript:Execute("createobject(""scripting.filesystemobject"")"
set "vbsBegin=%vbsBegin%.GetStandardStream(1).write("
set ^"vbsEnd=):close"^)":: Get yesterday's datefor /f %%Y in ('%vbsBegin% date-1 %vbsEnd%') do set Yesterday=%%Yset Yesterday
pause
echo(:: Get pifor /f %%P in ('%vbsBegin% 4*atn(1) %vbsEnd%') do set PI=%%Pset PI
pause
echo(set "var=name=value"echo Before - %var%:: Replace =for /f "delims=" %%S in (
'%vbsBegin% replace(""%var%"",""="","": "") %vbsEnd%') do set "var=%%S"echo After - %var%pause
echo(echo Extended ASCII:for /l %%N in (0,1,255) do (
%= Get extended ASCII char, except can't work for 0x00, 0x0A. =%
%= Quotes are only needed for 0x0D =%
%= Enclosing string quote must be coded as "" =%
%= Internal string quote must be coded as """" =%
for /f delims^=^ eol^= %%C in (
'%vbsBegin% """"""""+chr(%%N)+"""""""" %vbsEnd%'
) do set "char.%%N=%%~C"
%= Display result =%
if defined char.%%N (
setlocal enableDelayedExpansion
echo( %%N: [ !char.%%N! ]
endlocal ) else echo( %%N: Doesn't work :()pause
echo(:: Executing the mini VBS script directly like the commented code below
:: will not work because mshta fails unless stdout has been redirected:: or piped.:::: %vbsBegin% ""Hello world"" %vbsEnd%:::: But this works because output has been piped%vbsBegin% ""Hello world"" %vbsEnd% | findstr "^"pause2014-04-27在DosTips有一个伟大的汇编JS/VBS/html/HTA杂交和cmd/bat中的嵌合体..很多来自不同的人的好东西。在这个线程中,DosTips用户liviu发现了一个漂亮的VBS/批处理混合使用WSF的解决方案。<!-- : Begin batch script@echo off
cscript //nologo "%~f0?.wsf"exit /b----- Begin wsf script ---><job><script language="VBScript">
WScript.Echo "VBScript output called by batch"</script></job>我觉得这个解决方案太棒了。批处理部分和WSF部分显然由很好的头分隔。批处理代码是绝对正常的,没有任何奇怪的语法。唯一的限制是批处理代码不能包含-->.类似地,WSF中的VBS代码是绝对正常的。唯一的限制是vbs代码不能包含</script>.唯一的风险是非法使用"%~f0?.wsf"作为要加载的脚本。解析器以某种方式正确地找到并加载正在运行的.bat脚本"%~f0",以及?.wsf后缀神秘地指示CSCRIPT将脚本解释为WSF。希望微软永远不会禁用这个“功能”。由于解决方案使用WSF,批处理脚本可以包含任意数量的独立VBS、JScript或其他可以选择性调用的作业。每个作业甚至可以使用多种语言。<!-- : Begin batch script@echo off
echo batch output
cscript //nologo "%~f0?.wsf" //job:JS
cscript //nologo "%~f0?.wsf" //job:VBSexit /b----- Begin wsf script ---><package>
<job id="JS">
<script language="VBScript">
sub vbsEcho()
WScript.Echo "VBScript output called by JScript called by batch"
end sub
</script>
<script language="JScript">
WScript.Echo("JScript output called by batch");
vbsEcho();
</script>
</job>
<job id="VBS">
<script language="JScript">
function jsEcho() {
WScript.Echo("JScript output called by VBScript called by batch");
}
</script>
<script language="VBScript">
WScript.Echo "VBScript output called by batch"
call jsEcho </script>
</job></package>