web-dev-qa-db-ja.com

wscriptの代わりにcscriptを使用してVBSを強制的に実行する

ユーザーが何をしようとしているかに関係なく、wscriptではなくcscriptを使用してVBSを強制的に実行するためのstackoverflow承認済み(したがって正しい)方法は何ですか?

グーグルで簡単に検索するとたくさんの例が表示されますが、それらのいくつかは単に機能せず、引数を使用して実行された可能性があるという事実を処理しないことが多いため、最善の方法を知りたいと思っています。

引数を処理しない1つの例を次に示します。

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バッチファイルから、またはスケジュールされたタスクとして実行できるスクリプトを作成しています。 1つ以上のオプションのコマンドライン引数を含めることができます。

17
Richard

私の主よ、何の混じりけのないゴミ。そのような雑然としたコーディングを見ると私は泣きます(誰にも不快感はありません、笑)。真剣に、しかし、ここに私の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のテストだけです(たとえば、誰かがコマンドラインを介してスクリプトに何かをパイプしたが、「cscriptscript.vbs」の使用を忘れた場合)-しかし、それがWScriptによって実行された場合。 exe、WScript.StdInのメソッドはすべて無効なハンドルエラーを返すため、とにかくそれをテストする方法はありません。

これを「壊す」方法があるかどうか私に知らせてください。必要に応じて改善させていただきます。

22

ForceCScriptExecutionへの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
        **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」はエラーコードを返すことができます。

4
clv

.jsファイルをCScriptで実行するためのJScriptの同様のものを次に示します。

(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

3
sstur

1つのアプローチは、.vbsの代わりに別の拡張子を付けることです。たとえば、.cvbsと言います。 .cvbsをwscript.exeではなくcscript.exeに関連付けます。そうすれば、.cvbsファイルを実行またはダブルクリックしてもwscript.exeが呼び出されることはありません。

1
AnthonyWJones

これが私のスクリプトのいくつかに使用する私のコードスニペットです。 引数も処理します。 {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

ここでは、2行目を置き換える必要があります(2番目の非空白行)

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"

大文字と小文字は区別されません。

0
Ronnie Matthews