Quelle est la méthode approuvée (et donc correcte) de stackoverflow pour forcer un serveur VBS à s'exécuter à l'aide de cscript au lieu de wscript - indépendamment de ce que l'utilisateur tente?
Une recherche rapide sur Google montre de nombreux exemples, mais certains d'entre eux ne fonctionnent tout simplement pas et ceux qui le font souvent ne gèrent pas le fait qu'il ait peut-être été argumenté, alors je tiens à savoir quelle est la meilleure solution.
Voici un exemple qui ne gère pas les arguments:
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
Je comprends que cela pourrait probablement être facilement modifié pour gérer les arguments, mais sachez que ce n'est peut-être pas la meilleure façon d'aborder le problème.
Contexte: j'écris un script qui peut être exécuté en double-cliquant sur ou (probablement) à partir d'un fichier de commandes DOS ou en tant que tâche planifiée. Il peut contenir un ou plusieurs arguments de ligne de commande facultatifs.
Mon Seigneur, quelles ordures sans mélange. Cela me fait pleurer de voir un tel code cruddy (aucune offense à personne, lol). Sérieusement, voici mes 2 pence:
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
Il gère les arguments ET recherche les espaces dans lesdits arguments - de sorte que dans le cas d'un nom de fichier transmis à l'instance de script d'origine contenant des espaces, il ne serait pas "tokenisé" lorsqu'il est passé à cscript.exe.
La seule chose qu’elle ne fait pas, c’est tester StdIn (par exemple, dans le cas où une personne transmettrait quelque chose au script via la ligne de commande, mais oubliant d’utiliser "cscript script.vbs"), mais s’il était exécuté par WScript. exe, les méthodes de WScript.StdIn renvoient toutes des erreurs de type Invalid Handle. Il n’ya donc aucun moyen de tester cela.
N'hésitez pas à me faire savoir s'il existe un moyen de "casser" ceci; Je suis disposé à l'améliorer si nécessaire.
Deux petits ajouts à forceCScriptExecution me permettent de voir sa fenêtre après la fin et de gérer son code de retour.
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
Remarques: "cmd/k" laisse les fenêtres rester après l'exécution. Le paramètre "1" active la fenêtre. Le paramètre "true" attend la fin, la variable "ret" peut donc renvoyer le code d'erreur.
Voici un exemple similaire dans JScript pour faire en sorte que les fichiers .js soient exécutés dans 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();
Une approche pourrait être de lui donner une autre extension au lieu de .vbs. Dites .cvbs par exemple. Associez .cvbs à cscript.exe et non à wscript.exe. De cette manière, l’exécution ou le double-clic sur un fichier .cvbs n’appellera jamais wscript.exe.
Voici l'extrait de code que j'utilise pour certains de mes scripts. Il gère également les arguments . Tout ce que vous avez à faire est de remplacer {EnterWorC} par un "w" ou un "c" WITH quotes
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
Ici, vous devrez remplacer la 2ème ligne (2ème ligne non vide)
WorC={EnterWOrC} 'Make sure you replace "{EnterWOrC}" with a "w" or a "c" and BE SURE TO PUT QUOTES AROUND THE LETTER.
Pour Wscript: WorC="W"
Pour CScript: WorC="C"
Ce n'est pas sensible à la casse.