从批处理脚本执行WshShell命令

我有一个简单的问题:

Windows批处理(.bat)脚本执行单个WshShell命令的最佳方法是什么?

(希望它不是用VB代码创build一个新文件)

您可以通过VBScript或Jscript访问WshShell。 两者都可以嵌入批处理文件中,但JScript更清晰。

大多数人通过编写一个临时VBS文件批量执行VBScript。 但是可以在没有临时文件的情况下进行。 请参阅是否可以在批处理文件中嵌入和执行VBScript而不使用临时文件? 为各种选择。

在批处理中嵌入JScript非常简单。 请参阅https://stackoverflow.com/a/5656250/1012053 我使用这种技术的一个非常微小的变化。

@if (@X)==(@Y) @end /* Harmless hybrid line that begins a JScript comment :: ******* Begin batch code ********* @echo off :: Your batch logic goes here :: At any point you can execute the following to access your JScript cscript //E:JScript //nologo "%~f0" yourJscriptParametersGoHere :: Be sure to terminate your script so that :: it does not fall through into the JScript code exit /b ********* Begin JScript code **********/ var WshShell=WScript.CreateObject("WScript.Shell") /* do whatever with your WshShell object */ 

说明:

技术的关键是第一行。 它必须是对JScript和批处理都有有效语法的行。

批量看到第一行是一个简单的IF命令,总是计算为false,所以它永远不会执行不存在的@end命令,也不会造成任何危害。 以下行是所有正常的批处理代码,直到达到退出/ b,此时批处理终止,其余行被忽略。

JScript将第一行看作空的条件编译块,然后是多行注释的开始。 JScript忽略了以下批处理代码,因为它全部是注释的一部分。 注释以*/结尾,然后是普通的JScript代码。

唯一可能会失败的是如果你的批处理代码必须有*/ ,因为这会过早地终止JScript注释。 但是,可以通过在*/之间放置批处理后消失的东西来解决。 如果代码没有被引用,那么你可以简单地使用下面的斜线来逃避: *^/ 如果代码被引用,则可以展开未定义的变量: *%=%/ 名为=的变量保证不被定义。

这是我用来编写Batch-JScript混合脚本的方法:

 @if (@CodeSection == @Batch) @then :: The first line above is... :: in Batch: a valid IF command that does nothing. :: in JScript: a conditional compilation IF statement that is false, :: so this section is omitted until next "at-sign end". @echo off rem EXPR.BAT: Evaluate a JScript (arithmetic) expression rem Antonio Perez Ayala rem Define an auxiliary variable to call JScript set JSCall=Cscript //nologo //E:JScript "%~F0" rem Do Batch business here, for example: %JSCall% %1 goto :EOF End of Batch section @end // JScript section WScript.Echo(eval(WScript.Arguments.Unnamed.Item(0))); 

例如:

 EXPR 1/3 

编辑 :如果你想要一个更简单/更短的方法,使用这一个:

 @set @a=0 /* @cscript //nologo //E:JScript "%~F0" "%~1" @goto :EOF */ WScript.Echo(eval(WScript.Arguments(0))); 

同样,第一个@set @a=0 /*在JScript和Batch中都是有效的语句/命令,仅用于插入JScript注释(/ *)的开头,所以Batch部分将被JScript忽略。 在最后的goto :EOF后,注释被关闭(* /)。

感谢上面的激励我做一个小小的修改。

 @if (false)==nul ======= CMD code ======= @echo off ::code before Cscript cscript //nologo //e:jscript "%~f0" %* echo it returns: %errorlevel% ::code after Cscript exit /b ================================= Freedom Land ^o^ ======= J/VB Script code ====== @end // Start Cscript WScript.Echo("wsh says: Hello, Universe!"); WScript.Quit(123.456)