2011-01-14 13 views
16

Co to jest zatwierdzona przez stackoverflow (a przez to poprawna) metoda wymuszania uruchomienia VBS przy użyciu cscript zamiast wscript - niezależnie od tego, co użytkownik spróbuje?Wymuszenie uruchomienia VBS przy użyciu cscript zamiast wscripta

Szybkie wyszukiwanie w Google pokazuje wiele przykładów, ale niektóre z nich po prostu nie działają, a te, które często nie radzą sobie z faktem, że mogły być uruchamiane z argumentami, więc bardzo chciałbym wiedzieć, najlepszym sposobem jest.

Oto jeden przykład, który nie obsługuje argumenty:

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 

Doceniam, że to prawdopodobnie mógłby być łatwo modyfikowane do obsługi argumentów, ale uświadomić sobie, że to może nie być najlepszym sposobem podejścia do problemu.

Tło: Piszę skrypt, który można uruchomić przez podwójne kliknięcie lub (najprawdopodobniej) z pliku wsadowego DOS lub zaplanowanego zadania. Może zawierać jeden lub więcej opcjonalnych argumentów wiersza poleceń.

+0

Dodaj obsługę WScript.Arguments i gotowe. –

+0

@Kyle: brzmi jak odpowiedź do mnie, nie komentarz. – AnthonyWJones

+0

Wygląda na to, że odpowiedziałeś sam, właśnie to potwierdziłem. –

Odpowiedz

19

Mój Panie, co za nieskalane śmieci. To sprawia, że ​​płaczę, widząc takie zgryźliwe kodowanie (bez obrazy dla nikogo, lol). Poważnie jednak, oto moja 2 pensy:

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 

Obsługuje argumentów i czeki dla przestrzeni we wspomnianych argumentów - tak, że w przypadku pliku przekazany do oryginalnego przykład skryptu, który zawierał spacje, to byłoby miło” t dostanie "tokenized" po przekazaniu do cscript.exe.

Jedyne czego nie robi to test na StdIn (np. W przypadku, gdy ktoś wysłał coś do skryptu za pomocą wiersza poleceń, ale zapomniał użyć "cscript script.vbs") - ale jeśli był wykonywane przez WScript.exe, wszystkie metody WScript.StdIn zwracają błędy Invalid Handle, więc i tak nie ma możliwości ich przetestowania.

Proszę dać mi znać, czy istnieje sposób, aby to "zepsuć"; W razie potrzeby chcę ją poprawić.

+1

Przyjemne użycie '// nologo' i dobrze zapamiętane w teście przestrzeni (a następnie dodaniu cudzysłowów) dla każdego argumentu. – Richard

+1

W linii CreateObject brakuje spacji między nazwą skryptu a argumentami. W związku z tym polecenie run kończy się niepowodzeniem. Aby naprawić, zmień 'WScript.ScriptFullName &" "" & Str' na 'WScript.ScriptFullName &" "" "& Str'. – Richard

+1

FYI: Dokonałem edycji skryptu, aby uwzględnić spacje typu space/add, aby lepiej wyświetlać kod na stronie. Uświadomiłem sobie jednak, że przestrzeni nie brakuje - podczas pętli for są poprzedzane wszystkie argumenty. Oprócz oddzielania argumentów od siebie, pierwszy z nich oddziela je od nazwy skryptu. – JohnLBevan

1

Jednym ze sposobów może być dodanie innego rozszerzenia zamiast .vbs. Powiedz na przykład .cvbs. Powiąż plik .cvbs z cscript.exe, nie wscript.exe, w ten sposób wykonanie lub podwójne kliknięcie pliku .cvbs nigdy nie wywoła pliku wscript.exe.

+0

Niestety to nie zadziała, ponieważ nie mam kontroli nad komputerem, na którym uruchomiony zostanie ten skrypt. Muszę być w stanie podać im mycode.vbs i wiem, że jakkolwiek spróbują go uruchomić, zawsze będzie działać z cscript zamiast wscript. – Richard

3

Oto jeden podobny w JScript do tworzenia js plików uruchamianych w 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

Dwa małe dodatki do forceCScriptExecution pozwól mi zobaczyć jego okno po zakończeniu i obsługiwać swój kod zwrotny.

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 

Uwagi: "cmd/k" niech okna pozostają po wykonaniu. Parametr "1" aktywuje okno. Parametr "true" czeka na zakończenie, więc zmienna "ret" może zwrócić kod błędu.

0

Oto fragment kodu, którego używam w przypadku niektórych moich skryptów. Obsługuje również Argumenty.Wszystko co musisz zrobić, to wymienić {EnterWorC} albo "W" lub "C" cytatami

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 

Tutaj trzeba będzie wymienić 2 linia (2nd NON-pusty wiersz)

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

Dla Wscript: WorC="W"

Dla CScript: WorC="C"

nie jest uwzględniana wielkość liter.

Powiązane problemy