#javascript #jscript #internal #wsh
#javascript #jscript #внутренняя #wsh
Вопрос:
фон
У меня есть JScript
скрипт, запущенный под WSH
.
Сценарий довольно прост. Он перебирает список строк, каждую строку, JScript
саму себя и запускает каждый «внутренний» скрипт.
Проблема
Возможно, что какой-то «внутренний» скрипт может вызвать метод Quit. Это приводит к остановке основного скрипта, что нежелательно.
Простой пример
var strSomeScript = "WScript.Quit(1)";
var F = new Function(strSomeScript);
var exitCode = (F)();
WScript.Echo("Continue doing more things...");
последняя строка не будет выполнена, поскольку «внутренний» скрипт останавливает выполнение.
Вопрос
Если у меня нет контроля над содержимым «внутренних» скриптов, как я могу предотвратить их нарушение моего основного потока.
Требования
Мне нужно запускать каждый «внутренний» скрипт, ждать его завершения и сохранять его код выхода.
Комментарии:
1. Можете ли вы создать подпроцесс вместо
eval
прямого ввода объекта?2. Если вы не контролируете содержимое и не доверяете автору, вам вообще не следует запускать скрипты. Всегда есть способ все испортить, и гораздо хуже, чем просто выйти из игры.
3. @Bergi возможно, утверждение » отсутствие контроля » немного неумеренно. Я абсолютно доверяю авторам, но вместо того, чтобы принуждать авторов НЕ использовать
Quit
, я хочу справиться с этим со своей стороны.4. @Bergi не уверен, знаю ли я, как запустить подпроцесс
5. @idanshmu:
var WshShell = new ActiveXObject("WScript.Shell"); WshShell.Run("wscript.exe foo.js");
Ответ №1:
Если вы хотите только предотвратить конкретные WScript.Quit
вызовы, вы можете просто очистить свой ввод с помощью простой замены. (*) Если вы хотите иметь возможность предотвратить любой способ остановки скрипта — например, var x = WScript; x.Quit();
— вы в основном пытаетесь решить проблему остановки, которая, как я слышал, довольно сложна.
Если бы вы использовали обычный JS, вы могли бы попробовать что-то вроде:
WScript.Quit = function(e) {
// Assume there's something reasonable to put here
};
или:
var __WScript = WScript;
WScript = { ConnectObject: function(obj, pref) { __WScript.ConnectObject(obj, pref); },
CreateObject: function(progid, pref) { __WScript.CreateObject(obj, pref); },
... };
Но WScript
объект не реализует IDIspatchEx
и т. Д., Так что это не сработает.
Единственный способ убедиться, что произвольная строка, интерпретируемая как код JavaScript, не завершает ваш скрипт, — это не eval
использовать эту строку как часть вашего скрипта, а скорее запустить ее в совершенно новом контексте. (И вызов Function
contrcutor для этой строки, а затем вызов результирующего объекта — это почти то же eval
самое, что и его редактирование.)
Вы можете записать его в файл и выполнить wscript.exe
с этим файлом в качестве аргумента или использовать элемент управления Microsoft Script, если вы не хотите записывать файл на диск и / или хотите предоставить скрипту доступ к объектам из родительского скрипта.
(*) Не то, чтобы это имело какой-либо смысл в любом случае. Допустим даже, что ваша единственная проблема WScript.Quit
. Что вы собираетесь поставить вместо этого? return
? Это не остановит его:
function bar(a) {
if (Pred(a)) {
WScript.Quit(123);
}
return 456;
}
function foo() {
var x = bar(789);
if (!x) {
DoSomethingBad();
}
}
foo();
Скрипт, который раньше заканчивался беззвучно, теперь делает что-то плохое. Если вы «знаете», что изменение WScript.Quit
to return
не делает ничего плохого, вы также должны знать, что в коде вообще нет никаких WScript.Quit
s.
Просто нет ничего разумного, что вы могли бы сделать вместо выхода, даже если бы вы могли перехватывать каждый вызов WScript.Quit
.