Предотвращение выполнения внутренней функции, останавливающей основное выполнение

#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 .