Windows 从批处理脚本执行WshShell命令

Windows 从批处理脚本执行WshShell命令,windows,batch-file,wsh,Windows,Batch File,Wsh,我有一个简单的问题: 从Windows批处理(.bat)脚本执行单个WshShell命令的最佳方式是什么 (希望不是用VB代码创建新文件)您可以通过VBScript或Jscript访问WshShell。两者都可以嵌入到批处理文件中,但JScript要干净得多 大多数人通过编写临时VBS文件在批处理中执行VBScript。但是不需要临时文件也可以做到这一点。有关各种选项,请参见 在批处理中嵌入JScript非常容易。看见我使用了这种技术的一个非常微小的变化 @if (@X)==(@Y) @end

我有一个简单的问题:

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


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

您可以通过VBScript或Jscript访问WshShell。两者都可以嵌入到批处理文件中,但JScript要干净得多

大多数人通过编写临时VBS文件在批处理中执行VBScript。但是不需要临时文件也可以做到这一点。有关各种选项,请参见

在批处理中嵌入JScript非常容易。看见我使用了这种技术的一个非常微小的变化

@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命令,也不会造成任何伤害。在到达“退出”之前,以下行都是正常的批处理代码,此时批处理终止,其余行被忽略

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


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

这是我用来编写批处理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

结束后,评论关闭(*/)。感谢上面鼓励我做一些轻微的修改

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

您还可以使用适用于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")

0并不是说我会经常使用这种方法,而是说你的脚本是如何工作的?啊,这就是我想从你对我问题的回答中得到的解释。将编辑您的回复并复制注释行。