Консультация № 189235
21.04.2016, 15:49
0.00 руб.
21.04.2016, 16:34
0 10 1
Уважаемые эксперты, кто знает простой способ управления авто-закрытием окон в Консольном режиме VBScript ?
В больших программах очень удобно обозревать ход процесса в большом окне с прокруткой. Но когда мой скрипт авто-перезапускается из графического окна в консоль, то утрачивается возможность видеть сообщения об ошибках, тк в случае ошибки CScript-окно мигом закрывается ("вылет из проги", что это было?).
Я стал делать перезапуск в Cmd-окно, а внутри него запускаю CScript-окно. Код вроде простой:
Код:
Set FSO=CreateObject("Scripting.FileSystemObject") 'подключил объект FileSystemObject .
Set oShel=CreateObject("WScript.Shell") : Argums="" 'аргументы скрипта, в данном примере - пустая строка.
if LCase(FSO.GetBaseName(WScript.FullName))="wscript" then 'если режим ещё графический, то перезапускаю
oShel.Run "Cmd /c Title Заголовок окна &CScript /NoLogo MyScript.vbs " & Argums &_
"&Echo Готово! Жми любую клавишу закрыть окно.&Pause>nul &Exit"
WScript.Quit(0) 'Закончил исполнени в графи-окне, скрипт пере-запущен в Консоль-режим.
End if
WScript.Echo "Мы в Консоли. Тут у меня прокручивается много экранов."
MsgBox "Стоп-задержка авто-закрытия окна." & vbLf & "Жми ОК, и управлени возвратится в Cmd",,"Конец скрипта."

Всё было хорошо много месяцев. Почти каждый мой скрипт в начале проверяет наличие параметра QuickEdit в реестр-разделе HKCU\Console\%SystemRoot%_system32_cmd.exe и при необходимости окультуривает свойства Cmd-окна, чтоб оно стало почти на весь экран с удобным шрифтом и возможностями копи-вставки.
Но в более сложных программах приходится запускать дочерние окна (закачка антивир-баз в локальную папку, Rar-упаковка…). Мне не трудно закрыть родитель-окно вручную, но пользователей моих скриптов раздражает доп-окно или его кнопка в Панели задач.

Чтоб программно закрыть родитель-окно я перед [&Echo Готово!…] дописал условный без-паузный выход [&&Exit ] . А сразу после команды вызова дочернего окна добавил команду WScript.Quit(0) . После неё Родитель передаёт пра-родителю Cmd КодВозврата=0 , и Cmd-окно закрывается мигом. Работает т-ко одно дочернее окно. А в случае ошибки CScript возвращает в Cmd КодВозврата<>0, и пользователь видит причину ошибки в НЕ-закрытом окне.

Но что-то не доработал Microsoft, некоторые ошибки (деление на 0, чтение несуществующего элемента массива…) закрывают CScript с кодом=0 , от него моё Cmd-окно закрывается мигом, не отобразив причину ошибки.

Мне пришлось в случае успеха закрывать CScript НЕ-нулевым уникальным Кодом выхода 555 [командой WScript.Quit(555) ], и заменить "Cmd /c… &&Exit …" на более сложную распознавалку:
Код:

"Cmd /v:on /c Title Заголовок окна &CScript /NoLogo MyScript.vbs " & Argums &_
" &Echo Готово! Жми любую клавишу закрыть окно.&if not !errorlevel!==555 Pause>nul &Exit

Ошиб-вылеты прекратились, прог-закрытие окна стало управляемо, скрипт работает и радует, но слишком много конструкций. Может, кто подскажет метод по-изящнее?

Обсуждение

давно
Мастер-Эксперт
259041
7459
21.04.2016, 15:59
общий
Удалите пожалуйста повтор-строки 01…08 в нижнем тэг-блоке Код.
Я вставлял в этот блок т-ко 2 строки, получившие NN 09 и 10. В моём черновике даже выделение осталось на копируемом фрагменте. Но произошёл глюк, возможность Предпросмотра отсутствует в форме Вопроса, редактировать / удалить вопрос тоже невозможно.
давно
Посетитель
7438
7205
21.04.2016, 16:35
общий
Адресаты:
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Мастер-Эксперт
259041
7459
22.04.2016, 02:10
общий
Адресаты:
Спасибо, Игорь Витальевич, за правку текста моего Вопроса!
Я тут один программирую в 100-километровом окружении, обменяться опытом НЕ с кем. Я подумал, неужели и программисты Microsoft городят в своём прог-продукте такой же огород, чтоб переходить из окна в др консоль-окно со страховкой НЕ-вылета в случае ошибки? Может, я просто чего не знаю?
давно
Профессионал
848
1596
22.04.2016, 08:23
общий
Адресаты:
Чтобы не придумывать костыли, лучше перейдите на более продвинутый скриптовый язык. Например AutoIt, русскоязычный форум, он обладает интуитивно понятным бейсико-подобным синтаксисом. На выходе возможно получать готовые EXE файлы не требующие дополнительные библиотеки.
давно
Мастер-Эксперт
259041
7459
22.04.2016, 10:44
общий
Адресаты:
Спасибо Вам за доброе желание помочь.
"На выходе возможно получать готовые EXE файлы" - я год назад окончил курс "Программирование на Lazarus" на www.intuit.ru/studies/courses/13745/1221/info и что-то разочаровался в exe-файлах. Они объёмные и плохо-сжимаемые, требуют компилятора, где-то вне дома подправить свою exe-прогу проблематично. А компактный vbs прост, содержит встроенные легко-читаемые комменты и доступен везде!

На предложенном Вами рус-форуме http://autoit-script.ru/ отображаются какие-то далёкие от моих нужд темы: Автоматизация IE и Web-интерфейса, Поиск цвета пикселя на полупрозрачной картинке, хук сетевых функций в целевом процессе…
Нужной мне темы по работе с файлами и папками я не увидел, в строке поиска я задал "Список файлов". Мне в ответ: "Из-за большой загрузки сервера, функция поиска временно отключена".

Я верю Вам, что AutoIt имеет больше возможностей. Изучать их - потребуется много времени и сил при отсутствии систематизированого учебника (искать нужное по темам). Боюсь, у меня будет "каша в голове", а что я получу?
Чтоб сравить простоту и удобство простейшей файловой операции м-ду языками VBScript и AutoIt я опробовал VBS-код:

f1="C:\Temp\МойФайл.lst" 'проверка существования файла (правее апострофа - коммент).
if FSO.FileExists(f1) then WScript.Echo "Файл",f1,"существует." : Else : WScript.Echo "Файл",f1,"НЕ существует."
Всего 2 строки на VBS. Как это будет на AutoIt ? - придётся объявлять переменные? Создавать exe - НЕ обязательно? Будет ли работать AutoIt-скрипт на чужом компе без установки AutoIt-ПО? Вряд ли?
давно
Профессионал
848
1596
22.04.2016, 12:06
общий
Адресаты:
Всего 2 строки на VBS. Как это будет на AutoIt ?

Код:
If FileExists("C:\windows\notepad.exe") Then
MsgBox(0,"Сообщение","Файл есть")
Else
MsgBox(0,"Сообщение", "Файла нет")
EndIf

Создавать exe - НЕ обязательно? Будет ли работать AutoIt-скрипт на чужом компе без установки AutoIt-ПО? Вряд ли?

Да, здесь возникает основное неудобство. Если AutoIt установлен на машине, то скрипты запускаются без компиляции. Для запуска на чужой машине нужен будет ЕХЕ и тогда скрипт невозможно будет редактировать.
Думаю да, это Вам будет сложнее для изучения, т.к. русскоязычную документацию еще и поискать придется...
давно
Мастер-Эксперт
259041
7459
22.04.2016, 12:21
общий
Адресаты:
На www.script-coding.com/AutiItX.html предложен компромиссный вариант использования инструментов AutoIt простым и привычным синтаксом VBScript . Достаточно импортирвть доп-dll в system32\ и зарегистрирвть её , это можно за 1 секунду пуском своего скрипта.
Как Вы думаете, корректно ли этот AutoItX3.dll закрывает окна?
давно
Профессионал
848
1596
22.04.2016, 12:38
общий
Адресаты:
через AutoItX3.dll доступны не все возможности этого языка.
пример
В архив я положил хелп-файл в котором описаны возможности через AutoItX3.dll.
Батник install установит и зарегестрирует библиотеку AutoItX3.dll в систему, после этого ей можно будет пользоваться через VBScript.
Так же приложил пример, который делает запуск калькулятора и закртие окна окна по заголовку.
давно
Мастер-Эксперт
259041
7459
23.04.2016, 07:12
общий
Адресаты:
Большое Спасибо Вам за предоставленные файлы и советы! Хорошо, если Вы оформите Ответ, и тогда читателям рассылки тоже пригодится Ваш метод для закрытия приложений, не предоставляющих программисту закрыв-команд.

Я опробовал Ваш test.vbs с предвари-открытыми 2мя окнами Калькулятора. Вопреки моему предположению test.vbs ч-з 5 секунд работы закрыл не все 3 Calc-окна (как ранее-опробованные мною утилиты), а только то, кот-е он открыл сам. Я закомментировал 2ю строку скрипта, чтоб он не запускал, а только закрывал Calc-окна. И снова он неожиданно закрыл одно окно, последнее из мною-открытых (а не оба и не нуль).

В моей Cscript-ситуации надо закрывать не последнее активное Cmd/Cscript-окно, а первое (Родительское, отработавшее). Поскольку я не знаю логику работы команды oAutoIt.WinKill , то для моего случая лучше всё-таки использовать мой "костыль", в котором Cmd закрывает сам себя по недвусмысленному Коду возврата из дочернего Cscript .
Для этого приходится городить доп-строку-распознавалку
" &Echo Готово! Жми любую клавишу закрыть окно.&if not !errorlevel!==555 Pause>nul &Exit"
Но её можно 1 раз присвоить в переменную qExit и использовать для нескольких перезапусков. А её объём 0,1кБ - в тысячи раз меньше доп-библиотеки AutoItX3.dll в 445кБ.

Меня удивляет политика корпорации Microsoft, кот-я продемонстрировала своё умение и желание создать удобнейший инструм Wscript , кот-й даже если работает "молча" (программист задал долгую обработку *.vbs без вывода на экран), то всё равно в случае ошибки он открывает окно и сообщает, в которой строке/операторе скрипта обнаружена ошибка - что очень радует после работы в cmd-файлах. Но при пере-запуске в консольный Cscript - почему-то происходит обратная ситуация: в сразу-открытом окне всё прекрасно отображается, но как только ошибка - вылет с сокрытием инфо об ошибке.

В литературе и сети предложен способ обработки Исключительных ситуаций (попытка зачитать несуществующий параметр сис-реестра) без вылета. Но там если не вставлять доп-команду анализа if Err.Number<>0 , то Cscript просто не исполняет ошиб-команду, нарушая этим алгоритм программы. Изредка случаются непредусмотренные ошибки, где "соломку не подстелил" (не вставил блок On Error Resume Next…)

Я ещё поискал в интернете в надежде, может кто знает "Недокументированные возможности" запуска Cscript . Но все русские Cscript-программисты либо страдают от ошиб-вылетов, либо перенаправляют вывод в лог, либо запускают Cscript в Cmd-оболочке.
давно
Профессионал
848
1596
25.04.2016, 11:39
общий
это ответ
Здравствуйте, Алексеев Владимир!
Восползьуйтесь библиотекой AutoItX3.dll из пакета языка AutoIt.
Возможности библиотеки можно реализовать через VBScript.
Пример запуска приложения и закрытие окна по тексту в заголовке:
[code lang=js]Set oAutoIt = WScript.CreateObject("AutoItX3.Control")
oAutoIt.Run "Calc.exe"
oAutoIt.Sleep 5000
oAutoIt.WinKill "Калькулятор", ""
[/code]
5
Большое Спасибо за помощь!
Форма ответа