从批处理脚本执行WshShell命令

时间:2013-03-01 22:12:50

标签: windows batch-file wsh

我有一个简单的问题:

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

(希望它不是用VB代码创建新文件)

4 个答案:

答案 0 :(得分:7)

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

大多数人通过编写临时VBS文件来批量执行VBScript。但是没有临时文件就可以做到这一点。有关各种选项,请参阅Is it possible to embed and execute VBScript within a batch file without using a temporary file?

在批处理中嵌入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和批处理的有效语法的行。

Batch将第一行看作一个总是求值为false的简单IF命令,因此它永远不会执行不存在的@end命令,并且不会造成任何损害。在达到exit / b之前,以下行都是正常的批处理代码,此时批处理将终止,其余行将被忽略。

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

唯一可能失败的是您的批处理代码中必须包含*/,因为这会过早终止JScript注释。但这可以通过在批量解析后消失的*/之间放置一些东西来解决。如果未引用代码,则可以按如下方式转义斜杠:*^/。如果引用了代码,则可以展开未定义的变量:*%=%/。保证名为=的变量不被定义。

答案 1 :(得分:7)

这是我用来编写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注释(/ *)的开头,因此JScript会忽略Batch部分。评论在最终goto :EOF之后关闭(* /)。

答案 2 :(得分:1)

感谢上面的鼓励我做一些修改。

@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)

答案 3 :(得分:0)

您还可以使用适用于node.js的此方法:

0</* ::

@echo off

    echo hello from batch

    rem -- CALLING NODE
    ::node "%~f0" %*

    rem -- CALLING CSCRIPT
    cscript //E:JScript //nologo "%~f0" %*

exit /b %errorlevel%


*/0;

// -- NODE CODE
//console.log('Hello from Node');

// -- JScript CODE 
WScript.Echo("Hello from JSCript")