4

我有一个简单的问题:

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

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

4

4 回答 4

8

您可以通过 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 和批处理都具有有效语法的行。

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

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

唯一可能失败的是您的批处理代码必须包含*/在其中,因为这会过早终止 JScript 注释。但这可以通过在批处理解析后消失的*和之间放置一些东西来解决。/如果代码没有被引用,那么您可以简单地转义斜杠,如下所示*^/:如果代码被引用,那么您可以扩展一个未定义的变量:*%=%/. =保证不会定义一个名为的变量。

于 2013-03-02T01:38:27.973 回答
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 部分。评论在 final 之后关闭 (*/) goto :EOF

于 2013-03-02T15:24:11.270 回答
2

感谢以上内容启发我进行轻微修改。

@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)
于 2014-07-12T17:29:47.917 回答
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")
于 2020-04-26T13:33:23.790 回答