execute WshShell command from a batch script

前端 未结 4 816
一生所求
一生所求 2020-12-03 16:38

I\'ve got a simple question:

What\'s the best way to execute a single WshShell command from a Windows batch (.bat) script?

(hopefully it\'s not creating

相关标签:
4条回答
  • 2020-12-03 16:49

    This is the method I use to write a Batch-JScript hybrid script:

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

    For example:

    EXPR 1/3
    

    EDIT: If you want a simpler/shorter method, use this one:

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

    Again, the first @set @a=0 /* is a valid statement/command in both JScript and Batch that is only used to insert the start of a JScript comment (/*), so the Batch section be ignored by JScript. The comment is closed (*/) after the final goto :EOF.

    0 讨论(0)
  • 2020-12-03 16:57

    You can access WshShell via VBScript or Jscript. Both can be embedded within a batch file, but JScript is much cleaner.

    Most people execute VBScript within batch by writing a temporary VBS file. But it is possible to do it without a temporary file. See Is it possible to embed and execute VBScript within a batch file without using a temporary file? for various options.

    Embedding JScript within batch is quite easy. See https://stackoverflow.com/a/5656250/1012053. I use a very slight variation of that technique.

    @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 */
    

    Explanation:

    The key to the technique is the first line. It must be a line that has valid syntax for both JScript and batch.

    Batch sees the first line as a simple IF command that always evaluates to false, so it never executes the non-existent @end command, and no harm is done. The following lines are all normal batch code until exit /b is reached, at which point batch processing terminates and the remaining lines are ignored.

    JScript sees the first line as an empty conditional compilation block, followed by the beginning of a multi-line comment. JScript ignores the following batch code because it is all part of the comment. The comment ends with */, and then normal JScript code follows.

    The only thing that could fail is if your batch code must have */ within it, because that would terminate the JScript comment prematurely. But that can be solved by putting something between the * and / that disappears after batch parsing. If the code is not quoted, then you can simply escape the slash as follows: *^/. If the code is quoted, then you can expand an undefined variable: *%=%/. A variable named = is guaranteed not to be defined.

    0 讨论(0)
  • 2020-12-03 16:59

    Thanks the above for inspiring me to do a slight modification.

    @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)
    
    0 讨论(0)
  • 2020-12-03 17:07

    You can also use this method that is applicable for 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 讨论(0)
提交回复
热议问题