I have a JScript
script running under WSH
.
The script is fairly simple. It iterates over a list of strings, each string, a JScript
itself, and run each "internal" script.
It is possible that some "internal" script, may call Quit method. This causes the main script to stop, which is not desired.
var strSomeScript = "WScript.Quit(1)";
var F = new Function(strSomeScript);
var exitCode = (F)();
WScript.Echo("Continue doing more things...");
the last line will not be executed since the "internal" script stops the execution.
If I have no control over the content of the "internal" scripts, how can I prevent them from breaking my main flow.
I need to run each "internal" script, wait for it to finish and store its exit code.
If you want only to prevent specifically WScript.Quit
calls you can simply sanitize your input with a simple replace. (*) If you want to be able to prevent any way of stopping the script - for example, var x = WScript; x.Quit();
- you're basically trying to solve the halting problem, which I hear is kind of hard.
If you were using regular JS you could have tried something like:
WScript.Quit = function(e) {
// Assume there's something reasonable to put here
};
or:
var __WScript = WScript;
WScript = { ConnectObject: function(obj, pref) { __WScript.ConnectObject(obj, pref); },
CreateObject: function(progid, pref) { __WScript.CreateObject(obj, pref); },
... };
But the WScript
object doesn't implement IDIspatchEx
etc. so that won't work.
The only way do make sure an arbitrary string, when interpreted as JavaScript code, doesn't end your script is not to eval
that string as part of your script, but rather run it in a brand new context. (And calling the Function
contrcutor on that string and then calling the resulting object is pretty much the same as eval
ing it.)
You can write it to a file and execute wscript.exe
with this file as argument, or use the Microsoft Script Control if you don't want to write a file to disk and/or want to give the script access to objects from the parent script.
(*) Not that this makes any sense either way. Lets even say that your only problem is WScript.Quit
. What are you going to put instead? return
? That's not going to cut it:
function bar(a) {
if (Pred(a)) {
WScript.Quit(123);
}
return 456;
}
function foo() {
var x = bar(789);
if (!x) {
DoSomethingBad();
}
}
foo();
A script that used to end silently now does something bad. If you "know" that changing the WScript.Quit
to return
doesn't do anything bad you should also know that there aren't any WScript.Quit
s in the code in the first place.
There's simply nothing sensible you can do instead quitting even if you could catch every call to WScript.Quit
.