26

Re: JScript: Проблема с WshScriptExec.Exec

На официальном сайте MSDN есть хороший пример.
Привожу чуть сокращенную, не оптимизированную, но рабочую версию исходного кода, который можно посмотреть, пройдя по ссылке.



var sh = new ActiveXObject('WScript.Shell');
var ex = sh.Exec('%comspec% /c dire');

var stdout = [];
var stderr = [];

while ( true ) {
	if ( ! ex.StdOut.AtEndOfStream ) {
		stdout.push(ex.StdOut.ReadLine());
		continue;
	}
	if ( ! ex.StdErr.AtEndOfStream ) {
		stderr.push(ex.StdErr.ReadLine());
		continue;
	}
	if ( ex.Status == 1 ) {
		break;
	}
}

WScript.Echo('\nEXIT CODE :\n' + ex.ExitCode);
WScript.Echo('\nSTDERR    :\n' + stderr.join('\n'));
WScript.Echo('\nSTDOUT    :\n' + stdout.join('\n'));
WScript.Quit();
( 2 * b ) || ! ( 2 * b )

27 (изменено: Rumata, 2014-11-16 16:08:33)

Re: JScript: Проблема с WshScriptExec.Exec

Мои последние эксперименты на Win7 Enterprise SP 1 показывают, что не все гладко с этим решением 3-годичной давности. Иногда вышеприведенный код не работает. Например, в случае запуска приложения, которое в случае успеха ничего не пишет в консоль и уходит в фоновый режим. Тогда пример выше зависает на первом if.

Приложение, запущенное в фоне возвращает статус ex.Status == 0, но проблема не в этом. Проблема именно в том, что стандартные потоки открыты/закрыты/заблокированы/ожидают (что-то еще?). Схожий пример я наблюдал в случае проверки STDIN:


// z.js
WScript.Echo ( WScript.StdIn.AtEndOfStream );

Если запустить "голый" скрипт, то он подвиснет, пока принудительно не завершите скрипт по CTRL-C:

cscript //nologo z.js

Любое перенаправление - завершает скрипт


:: выведет -1 (конец файла достигнут)
cscript //nologo z.js<nul

:: выведет 0 (есть данные, конец файла не достигнут)
cscript //nologo z.js<z.js
( 2 * b ) || ! ( 2 * b )

28 (изменено: daap, 2016-02-14 21:05:34)

Re: JScript: Проблема с WshScriptExec.Exec

Rumata пишет:

Тогда пример выше зависает на первом if

Похоже та же картина. Пытаюсь найти с одним консольным движком общий язык.

AtEndOfStream  и
ReadLine()

работают до тех пор, пока из потока чего-нибудь читается, когда доходит дело до того, что
AtEndOfStream  должно вернуть конец - зависон глубокий пока не вырубишь консоль дочернего процесса

че делать не понятно. другие ж GUI работают с движком этим как-то ....

похоже что поток как-то не завершается как положено. Или это такой постоянно открытый поток ..

29

Re: JScript: Проблема с WshScriptExec.Exec

daap пишет:

AtEndOfStream  и
ReadLine()

работают до тех пор, пока из потока чего-нибудь читается, когда доходит дело до того, что
AtEndOfStream  должно вернуть конец - зависон глубокий пока не вырубишь консоль дочернего процесса

че делать не понятно. другие ж GUI работают с движком этим как-то ....

похоже что поток как-то не завершается как положено. Или это такой постоянно открытый поток

(Сейчас не перепроверял, пишу по воспоминаниям…)

Да, AtEndOfStream возвращает истинное значение,  а ReadLine — пустую строку не в том случае, если поток пуст в данный момент, а если он закрыт, иначе — ждут пока в нём что-нибудь появится или он всё-таки наконец закроется.

Для проверки попробуйте в качестве «движка» сценарий WSH, в котором перед долгим Sleep отсутствует/присутствует WScript.StdOut.Close.

Если такое поведение «движка» не устраивает — перенаправьте его вывод в файл, — в этом случае будет определятся конец файла, если считано всё его текущее содержимое, даже если он не закрыт и в него может быть дописано что-то ещё.

30

Re: JScript: Проблема с WshScriptExec.Exec

Господа, помню, что беда метода ReadLine именно в том, что он ждёт появления перевода строки в StdOut. Поэтому если ничего не вернулось, то он реально повисает на этом моменте. Предполагаю, что Вам поможет метод Read, который читает N-ое количество символов. Вроде бы на форуме эта тема уже поднималась.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

31 (изменено: daap, 2016-02-16 00:19:25)

Re: JScript: Проблема с WshScriptExec.Exec

Xameleon

Спасибо друзья!   не думал что тут живенько так.
С этим  ReadLine - хрен с ним, он то работает после   AtEndOfStream

Зависает и чего-то ждет именно AtEndOfStream
Т.е. я не могу узнать когда закончились строки в потоке, где же последняя.
Видать да, движок не завершает поток. Он как бы асинхронный, одновременно и принимает и выдает в обе дырки.

Пока выручила идея такая.
Я всегда знаю что движок должен ответить на каждый из запросов. Например я ему - "Эй",  он мне всегда - "тут"
Поэтому составил таблицу вопрос-ответ - и у меня последняя строка всегда ожидаемый ответ и я принудительно выхожу из цикла.

Но это все как-то неправильно.  Вдруг он не выдаст ожидаемый ответ, тогда зависон позорный. Не хорошо.

К сожалению я не очень продвинутый програмер, я по своему - в 1С ковыряю.
С этим только столкнулся по причине одного хобби, замутить интересное дело захотелось.

Поэтому такие вещи:  "попробуйте в качестве «движка» сценарий WSH, в котором перед долгим Sleep отсутствует/присутствует WScript.StdOut.Close."   
меня вводят в ступор   :-)))

Кста, подозреваю что в этом СЛИП чета кроется хорошее.

"поможет метод Read"
надо это попробовать, хорошая идея, поищу примеры скриптов....
Т.е. надежда на то что  Read  как-то остановится?  Т,е. он читает сплошным текстом а не построчно? Это было бы гуд.
а вдруг он после последнего символа также залипнет?