【问题标题】:execute WshShell command from a batch script从批处理脚本执行 WshShell 命令
【发布时间】:2013-03-01 22:12:49
【问题描述】:

我有一个简单的问题:

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

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

【问题讨论】:

    标签: windows batch-file wsh


    【解决方案1】:

    您可以通过 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 将第一行视为一个简单的 IF 命令,该命令的计算结果始终为 false,因此它永远不会执行不存在的 @end 命令,也不会造成任何伤害。以下行都是正常的批处理代码,直到到达 exit /b,此时批处理终止并忽略其余行。

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

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

    【讨论】:

    • 并不是说我会经常使用这种方法,但是你的脚本是如何工作的?
    【解决方案2】:

    这是我用来编写 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 之后关闭(*/)。

    【讨论】:

    • 啊,这就是我正在寻找的关于您对我的问题的回答的解释。将编辑您的回复并复制评论行。
    【解决方案3】:

    感谢以上内容启发我做一些细微的修改。

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

    【讨论】:

      【解决方案4】:

      你也可以使用这个适用于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")
      

      【讨论】:

        猜你喜欢
        • 2012-09-19
        • 1970-01-01
        • 1970-01-01
        • 2012-08-30
        • 1970-01-01
        • 1970-01-01
        • 2011-11-17
        • 2012-04-25
        • 1970-01-01
        相关资源
        最近更新 更多