【问题标题】:Force a VBS to run using cscript instead of wscript强制 VBS 使用 cscript 而不是 wscript 运行
【发布时间】:2011-06-09 05:12:52
【问题描述】:

什么是 stackoverflow 批准(因此是正确的)方法来强制 VBS 使用 cscript 而不是 wscript 运行 - 无论用户尝试什么?

快速的 Google 搜索显示了很多示例,但其中一些根本不起作用,而那些通常无法处理它可能已经与参数一起运行的事实,所以我很想知道什么是最好的方式是。

这是一个不处理参数的例子:

sExecutable = LCase(Mid(Wscript.FullName, InstrRev(Wscript.FullName,"\")+1))
If sExecutable <> "cscript.exe" Then
  Set oShell = CreateObject("wscript.shell")
  oShell.Run "cscript.exe """ & Wscript.ScriptFullName & """"
  Wscript.Quit
End If

我明白这可能很容易修改以处理参数,但意识到这可能不是解决问题的最佳方法。

背景:我正在编写一个脚本,它可以通过双击或(很可能)从 DOS 批处理文件或作为计划任务运行。它可以包含一个或多个可选的命令行参数。

【问题讨论】:

  • 添加对 WScript.Arguments 的处理,然后您就设置好了。
  • @Kyle:听起来像是对我的回答而不是评论。
  • 好像是你自己回答的,我只是确认一下。
  • @Kyle:你说得对,但我想知道以这种方式查看 Wscript.FullName 的整个方法是否是最好的做法。或者引用 Perl,有不止一种方法可以做到……也许我的不是最好的?
  • 我想不出其他方法。

标签: vbscript arguments wsh


【解决方案1】:

这是我用于一些脚本的代码 sn-p。 它也处理参数。您所要做的就是将 {EnterWorC} 替换为“w”或“c”带引号

Dim WorC, Command, Arguments, I

WorC={EnterWOrC}  'Make sure you replace "{EnterWOrC}" with a "w" or a "c" and BE SURE TO PUT QUOTES AROUND THE LETTER.

WorC=LCase (WorC)
If lcase (WorC)="w" Or lcase (WorC)="c" Then

If LCase (Right (WScript.FullName,11))<> WorC & "script.exe" Then
    command=WScript.ScriptFullName
    Arguments=""
    For I=0 To UBound (WScript.Arguments)
        Arguments=Arguments & Chr (34) & WScript.Arguments(I) & Chr (34) & Space (1)
    Next
    CreateObject("Wscript.Shell").Run WorC & "script.exe " & Chr (34) & command & Chr (34) & Space (1) & Arguments, 1
    WScript.Quit
End If
    WorC=Empty
    Command=Empty
    I=Empty
    Arguments=Empty
End If

这里你必须替换第二行(第二个非空行)

WorC={EnterWOrC}  'Make sure you replace "{EnterWOrC}" with a "w" or a "c" and BE SURE TO PUT QUOTES AROUND THE LETTER.

对于 Wscript:WorC="W"

对于 CScript:WorC="C"

不区分大小写。

【讨论】:

    【解决方案2】:

    对 forceCScriptExecution 的两个小补充让我在终止后看到它的窗口并处理它的返回码。

    Sub forceCScriptExecution
        Dim Arg, Str
        If Not LCase( Right( WScript.FullName, 12 ) ) = "\cscript.exe" Then
            For Each Arg In WScript.Arguments
                If InStr( Arg, " " ) Then Arg = """" & Arg & """"
                Str = Str & " " & Arg
            Next
            **ret =** CreateObject( "WScript.Shell" ).Run **("cmd /k** cscript //nologo """ & WScript.ScriptFullName & """ " & Str**,1,true)**
            WScript.Quit **ret**
        End If
    End Sub
    

    注意:“cmd /k”让窗口在执行后停留。参数“1”激活窗口。参数“true”等待终止,所以变量“ret”可以返回错误码。

    【讨论】:

      【解决方案3】:

      这是 JScript 中类似的一个,用于使 .js 文件在 CScript 中运行:

      (function(ws) {
        if (ws.fullName.slice(-12).toLowerCase() !== '\\cscript.exe') {
          var cmd = 'cscript.exe //nologo "' + ws.scriptFullName + '"';
          var args = ws.arguments;
          for (var i = 0, len = args.length; i < len; i++) {
            var arg = args(i);
            cmd += ' ' + (~arg.indexOf(' ') ? '"' + arg + '"' : arg);
          }
          new ActiveXObject('WScript.Shell').run(cmd);
          ws.quit();
        }
      })(WScript);
      
      WScript.echo('We are now in CScript. Press Enter to Quit...');
      WScript.stdIn.readLine();
      

      https://gist.github.com/4482361

      【讨论】:

        【解决方案4】:

        我的主,多么纯粹的垃圾。看到如此粗俗的编码让我哭了(没有冒犯任何人,哈哈)。不过说真的,这是我的 2 便士:

        Sub forceCScriptExecution
            Dim Arg, Str
            If Not LCase( Right( WScript.FullName, 12 ) ) = "\cscript.exe" Then
                For Each Arg In WScript.Arguments
                    If InStr( Arg, " " ) Then Arg = """" & Arg & """"
                    Str = Str & " " & Arg
                Next
                CreateObject( "WScript.Shell" ).Run _
                    "cscript //nologo """ & _
                    WScript.ScriptFullName & _
                    """ " & Str
                WScript.Quit
            End If
        End Sub
        forceCScriptExecution
        

        它处理参数,并检查所述参数中的空格——因此,在传递给包含空格的原始脚本实例的文件名的情况下,它在传递给 cscript.exe 时不会被“标记化”。

        它唯一不做的就是测试 StdIn(例如,如果有人通过命令行将某些内容通过管道传输到脚本,但忘记使用“cscript script.vbs”)——但如果它被执行通过 WScript.exe,WScript.StdIn 的方法都返回 Invalid Handle 错误,所以无论如何都无法测试。

        如果有办法“打破”这一点,请随时告诉我;如有必要,我愿意改进。

        【讨论】:

        • 很好地使用了//nologo,并在每个参数的空格测试(然后添加引号)中很好地记住了。
        • CreateObject 行在脚本名称和参数之间缺少空格。因此,运行命令失败。要修复,请将WScript.ScriptFullName &amp; """" &amp; Str 更改为WScript.ScriptFullName &amp; """ " &amp; Str
        • 仅供参考:我编辑了脚本以包含空格/添加换行符以在现场更好地显示代码。但是我刚刚意识到空间并没有丢失 - 在 for 循环期间,所有参数都以空格为前缀。除了将参数彼此分开之外,其中的第一个将它们与脚本名称分开。
        【解决方案5】:

        一种方法可能是给它另一个扩展名而不是 .vbs。以 .cvbs 为例。将 .cvbs 与 cscript.exe 而不是 wscript.exe 关联,这样执行或双击 .cvbs 文件将永远不会调用 wscript.exe。

        【讨论】:

        • 遗憾的是,这不起作用,因为我无法控制运行此脚本的计算机。我需要能够给他们 mycode.vbs 并且知道无论他们如何尝试运行它,它都将始终使用 cscript 而不是 wscript 运行。
        • 它不会工作期间。这将导致Input Error: There is no script engine for file extension ".cvbs".
        猜你喜欢
        • 1970-01-01
        • 2015-04-28
        • 2011-09-02
        • 1970-01-01
        • 2017-06-13
        • 2014-05-29
        • 2010-09-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多