ユーザーが何をしようとしているかに関係なく、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つ以上のオプションのコマンドライン引数を含めることができます。
私の主よ、何の混じりけのないゴミ。そのような雑然としたコーディングを見ると私は泣きます(誰にも不快感はありません、笑)。真剣に、しかし、ここに私の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のメソッドはすべて無効なハンドルエラーを返すため、とにかくそれをテストする方法はありません。
これを「壊す」方法があるかどうか私に知らせてください。必要に応じて改善させていただきます。
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」はエラーコードを返すことができます。
.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();
1つのアプローチは、.vbsの代わりに別の拡張子を付けることです。たとえば、.cvbsと言います。 .cvbsをwscript.exeではなくcscript.exeに関連付けます。そうすれば、.cvbsファイルを実行またはダブルクリックしてもwscript.exeが呼び出されることはありません。
これが私のスクリプトのいくつかに使用する私のコードスニペットです。 引数も処理します。 {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"
大文字と小文字は区別されません。