Заставить VBS запускать cscript вместо wscript
Что такое одобренный 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
Я понимаю, что это, вероятно, легко изменить для обработки аргументов, но поймите, что это может быть не лучший способ подойти к проблеме.
Справочная информация. Я пишу script, который может выполняться двойным щелчком или (скорее всего) из пакетного файла DOS или в виде запланированной задачи. Он может содержать один или несколько необязательных аргументов командной строки.
Ответы
Ответ 1
Мой Господь, какой неподдельный мусор. Это заставляет меня плакать, чтобы увидеть такую грубую кодировку (никого не обидеть, LOL). Серьезно, хотя, здесь мои 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
Он обрабатывает аргументы и проверяет пробелы в указанных аргументах - так что в случае имени файла, переданного в исходный экземпляр script, который содержит пробелы, он не будет получать "токенизированные" при передаче в cscript.exe.
Единственное, чего он не делает, это тест для StdIn (например, в случае, когда кто-то передал что-то в script через командную строку, но забыл использовать "cscript script.vbs" ) - но если он был выполнен WScript.exe, методы WScript.StdIn возвращают ошибки Invalid Handle, поэтому в любом случае нет возможности проверить это.
Не стесняйтесь, дайте мне знать, есть ли способ "сломать" это; Я готов улучшить его, если это необходимо.
Ответ 2
Здесь аналогичный в 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
Ответ 3
Два небольших дополнения к 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" может вернуть код ошибки.
Ответ 4
Один подход может заключаться в том, чтобы дать ему другое расширение вместо .vbs. Скажем, например,.cvbs. Связать .cvbs с cscript.exe не wscript.exe, так что выполнение или двойное нажатие файла .cvbs никогда не вызовет wscript.exe.
Ответ 5
Вот мой фрагмент кода, который я использую для некоторых моих скриптов. Он также обрабатывает аргументы. Все, что вам нужно сделать, это заменить {EnterWorC} либо кавычками или WITH
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"
Это НЕ регистр чувствительный.