Windows — автоматизация задач с помощью скриптов. Интересные возможности WSH

Пожалуй, многие знают, что Windows начиная с версии 98 имеет по умолчанию в своем составе Windows Script Host (WSH), который позволяет исполнять скрипты на языках VBScript и JScript, но далеко не каждый хотя бы раз пользовался этой возможностью. В этой статье я приведу примеры полезных сниппетов и скриптов для WSH и попробую убедить вас в том, что вещь это действительно стоящая. Я также расскажу об очень занимательных и полезных возможностях WSH, о которых практически никто не знает, и информацию о которых в интернете найти весьма непросто.

Для начала немного о языках, поддерживающихся WSH. JScript - это, по сути, JavaScript с несколько измененной объектной моделью (например, в нем нет объекта window, как в браузерах, зато добавлен объект WScript, позволяющий взаимодействовать со средой, в которой исполняется скрипт). VBScript базируется на синтаксисе и возможностях Visual Basic 6 (и, возможно, более ранних версий). Оба языка имеют приблизительно одинаковые возможности. Кроме того, можно установить и другие языки для WSH, например, PerlScript, который, как вы уже догадались, базируется на Perl'е. Для этого следует воспользоваться, например, инсталлятором ActiveState Perl:

В Windows по умолчанию расширение файла .js ассоциировано с JScript-скриптами, .vbs - с VBScript. При установке PerlScript появляется ассоциация .pls - с PerlScript-скриптами. Скрипты js и vbs можно закодировать с помощью утилиты от Microsoft screnc.exe, получив на выходе файл с расширением .jse или .vbe, соответственно. К сожалению, такое кодирование защитит лишь от неопытных пользователей - множество раскодировщиков можно найти в Google. Кроме того, при закодировании бывают проблемы с русским текстом.

Еще одной замечательной особенностью WSH является то, что он позволяет комбинировать все установленные в системе скриптовые языки в одном файле с расширением .wsf. Например, VBScript предоставляет функцию, отображающую окошко для ввода текста (InputBox), и она вам очень нужна, но скрипт свой вы пишете на JScript, который такой функцией не располагает. Решается проблема очень просто - создать файл wsf со следующим содержанием:

Таким же образом можно скомбинировать, например, JScript и PerlScript, если PerlScript у вас установлен:

Небольшое отступление - расскажу о запуске скриптов для WSH. По двойному клику мышкой они по умолчанию запускаются с помощью программы wscript.exe. В этом случае все вызовы WScript.Echo транслируются в обычные messagebox'ы. Если вы используете скрипт для автоматизации какого-либо процесса, например, сборки какого-либо проекта, и желаете выводить множество сообщений, то следует скрипт запускать с помощью программы cscript.exe, которая обращения к WScript.Echo транслирует в выводы в консоль. Запустить скрипт в консольном варианте можно, создав bat-файл с примерно таким содержимым:

Можно также кликнуть на файле скрипта и вызвать меню "Open with command prompt".

Возможно, я кого-то удивлю, если скажу, что из скриптов для WSH можно с легкостью использовать классы .NET! Приведу пример на JScript (js-файл):

Выполнив этот скрипт, увидим такую форму:

И все это создано с помощью .NET-классов! Есть, правда, в этом некоторые сложности. Во-первых, я не нашел путей для взаимодействия с делегатами, которые используются при обработке событий в .NET. Во-вторых, не существует способа вызвать через CreateObject конструктор COM-объекта, принимающий параметры (это относится не только к .NET, кстати). В-третьих, по умолчанию в скриптах доступны лишь некоторые .NET-сборки и классы:

System.Collections.Queue
System.Collections.Stack
System.Collections.ArrayList
System.Collections.SortedList
System.Collections.Hashtable
System.IO.StringWriter
System.IO.MemoryStream
System.Text.StringBuilder
System.Random

С другой стороны, опубликовать .NET-сборку, чтобы она стала доступной через COM-интерфейсы (которые и используются в WSH), совсем несложно. Если вышеприведенный скрипт с Windows Forms у вас не заработал (что, скорее всего, так и есть), наберите в консоли команду:

либо, если вы пользуетесь 64-битной операционной системой, то

Эта команда опубликует сборку System.Windows.Forms и она станет доступной через COM-интерфейсы, после чего вы сможете использовать классы из нее в скриптах. К сожалению, не все сборки можно зарегистрировать, а только те, которые имеют аттрибут ComVisible=true (если такой аттрибут у сборки есть, об этом говорится на соответствующих страницах с описанием сборки в MSDN).

Для отмены регистрации сборки выполните приведенную выше команду с ключом /unregister.

Что еще следует знать при использовании .NET-сборок? Часто классы в .NET имеют перегруженные функции с одинаковыми именами и разными типами и количеством параметров. Как вызывать их? Ведь переменные в скриптах практически не типизируются! Все очень просто. Например, возьмем класс System.Random. Он уже зарегистрирован по умолчанию и доступен из WSH. Но он имеет три метода с именем Next. Как вызвать нужный? .NET маппит имена одинаковых методов следующим образом: первый с конца в таблице методов имеет имя Next (в данном случае), следующий - Next_2, далее - Next_3. Где увидеть эту таблицу с правильным порядком функций? Например, в ildasm'е:

Здесь я открыл сборку mscorlib.dll из %WINDIR%\Microsoft.NET\Framework64\v2.0.50727, после чего зашел в неймспейс System и нашел класс Random в нем. Теперь ясно - если мы хотим воспользоваться методом Next, предоставляющим возможность указать минимальное и максимальное значение при генерации рандома, то следует вызвать Next_2 (так как этот метод второй с конца в списке методов Next, смотрите скриншот выше):

Еще одной из интересных возможностей скриптов для WSH является поддержка drag-drop'а. На файлы .js, .vbs, .jse, .vbe, .wsf можно перетаскивать другие файлы, и их имена будут доступны через WScript.Arguments.

Итак, подведем итоги. Чем же примечательно написание скриптов на JScript, VBscript или PerlScript? Почему это лучше и проще bat-файлов или PowerShell'а?

[+] Вы сами выбираете знакомый любимый синтаксис. Предпочитаете JavaScript - пишите на нем, обожаете Visual Basic - тогда VBScript для вас!
[+] Вы можете комбинировать эти языки в одном скрипте, тем самым дополняя возможности одного языка фичами другого.
[+] Вам доступны все стандартные особенности выбранного языка. Поддержка выполнения внешних программ, работа с текстовыми и двоичными файлами, регулярные выражения и многое другое прилагается. Поддержка работы с файлами по маске, с сетевыми путями (samba, например) - тоже.
[+] Вы можете использовать множество зарегистрированных COM-классов.
[+] Вы можете использовать многие COM-Visible .NET-сборки.
[+] Вы можете работать с WMI, так как он доступен через COM.
[+] Имеется полная поддержка Unicode, достаточно сохранить файл как Unicode Little Endian.

Масса очевиднейших плюсов. На WSH можно писать мощнейшие приложения и скрипты, которые облегчат вам жизнь и сделают какие-то полезные задачи автоматически.

Сейчас мне остается лишь привести несколько полезных сниппетов, которые пригодятся вам, если вы решите использовать WSH для написания скриптов, производящих автоматическую сборку проектов/парсинг/работу с файлами и т.д. Для примера я буду использовать свой любимый JScript, потому что он имеет наиболее привычный синтаксис и будет понятен большинству из вас. Кроме того, в JScript удобно перехватывать исключения, которые могут быть выброшены функциями COM-классов и объекта WScript, с помощью try-catch. Можно и самим бросать исключения (это штатная возможность языка JavaScript, и, разумеется, она есть в JScript).

1. Работаем с файловой системой.

2. Работаем с переменными окружения.

3. Выполнение внешних программ.

Выполнение программы с ожиданием ее завершения и получением кода возврата:

Выполнение внешней программы с перехватом ее вывода:

Можно также вводить какие-либо данные в программу через Exec.StdIn.

4. Работаем с реестром Windows.

5. Работаем с WMI.

Перечисляем все вложенные ключи реестра в заданной ветке:

Такую вещь на VBScript можно сделать гораздо проще, как ни странно:

Выполнение запроса WMI (в этом примере - вывод всех аккаунтов на компьютере):

На этом я закончу свое повествование. Думаю, если вы осилили эту статью до конца, вы осознали всю мощь и удобство скриптов для WSH и непременно воспользуетесь этой замечательной функциональностью Windows!

Для дальнейшего изучения могу посоветовать MSDN (там есть множество документации по WSH, и, конечно же, .NET и WMI), и Google (примеров скриптов для WSH там несчетное количество). Удачи в изучении!

Windows — автоматизация задач с помощью скриптов. Интересные возможности WSH: 29 комментариев

  1. Весьма интересная статья, никогда не думал, что в винде есть что то подобное. Почему-то думал, что вся автоматизация ограничивается .bat командами.

  2. Действительно, очень интересно. Узнал много нового, так как до этого тоже юзал батники. Спасибо.

  3. >> Возможно, я кого-то удивлю, если скажу, что из скриптов для WSH можно с >>легкостью использовать классы .NET! Приведу пример на JScript (js-файл):

    Не совсем понял как запустить этот скрипт в винде, с расширением js смог запустить только в Notepad++, js - файлы открываются у меня в редакторе, переименовал в wsр-но получил ошибку "Сценарий не указан"

    1. У тебя, значит, Notepad++ имеет ассоциацию формата файлов js. По умолчанию они запускаются виндовой программой wscript.exe.

  4. При запуске скрипта, загружающего форму - ошибка: "Не удаётся найти класс программируемых объектов с именем "System.Windows.Forms.Form"".
    код - 80020009.
    ОС Windows Vista.
    Регистрация - %WINDIR%\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe System.Windows.Forms.dll не помогает.

  5. var form = new ActiveXObject("System.Windows.Forms.Form");//работает
    var gridView = new ActiveXObject("System.Windows.Forms.DataGridView");//работает
    var col = new ActiveXObject("System.Windows.Forms.DataGridViewColumn");//почему-то не работает :(

    сборку зарегистрировал

    1. Боюсь, делать сложные графические интерфейсы на скриптах с использованием COM - не лучшая идея. Из .NET далеко не все классы экспортируются в COM. Это можно узнать, открыв документацию и увидев строчку [ComVisibleAttribute(true)] перед объявлением класса - значит, такой класс экспортируется. А вот для DataGridViewColumn такой строчки нет, поэтому и не работает. Кроме того, .net-эвенты Вы через скрипты никак не реализуете.

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

  6. Не знаю поддерживаете ли вы эту тему. Просто у меня возникла проблема в написании скрипта.
    Скрипт такого рода:
    var WSHShell=WScript.CreateObject ("WScript.Shell");
    WSHShell.Run ("C:\name.exe",0);
    Запускаю его двойным щелчком, а он мне выдает:
    Не удается найти указанный файл Код: 80070002
    Что я не правильно сделал

    1. WSHShell.Run ("C:\\name.exe",0);
      Два обратных слэша надо. Иначе получается escape-последовательность "\n" - перевод строки.

    1. А язык важен? Проще всего, вероятно, на Perl, если нужен именно WSH. А если не нужен, то, наверное, еще проще на PowerShell скрипт написать.

  7. Добрый день! Подскажите пож-та, как можно управлять темами и дополнительными настройками Windows 7-XP(ПКМ НА МОЙ КОМПЬЮТЕР-СВОЙСТВА)? Необходимо убрать галки с некоторых доп. настроек-как можно это реализовать? перенести каталог TEMP НА диск С, и прописать его в системе автоматически? Перепрописать каталоги пользователя из C:\Users\Пользователь\Документы, загрузки рисунки, видео на D:\Documtnts, D:\Pictures, D:\Music итд? Как сменить тему на классическую, убрать эффекты итд?

  8. Скажите, с помощью этих скриптов можно, например, открыть Мозиллу Файрфокс, открыть страницу, сохранить страницу, отправить страницу на печать - а потом открыть другую страницу (ну, и так много раз)?

    1. Не уверен. Нужно смотреть, предоставляет ли мозилла фаерфокс какие-либо возможности для внешнего взаимодействия с ней, чтобы это можно было использовать из скриптов. Вроде бы что-то такое было, но я уже не помню. А так, для подобных вещей есть Selenium.

  9. Огромное спасибо за статью! Очень много чего нового и важного открыл для себя.
    Вопрос такой:
    Можно ли использовать закрытые классы, элементы управления (Windows.Forms) сборок .NET в не управляемом коде?
    Может есть некие wrapperы или мосты?
    Мое приложение позволяет подключать ActiveX элементы управления, работать с COM. Хочется взять .NET и работать с ним через COM, даже с теми объектами, которые COM-Visible(False)

    1. Думаю, что com-visible(false) использовать все же не получится в скриптах. Если только самому писать сборку на .NET, которая обернет нужные фичи и сделает их доступными через COM.

      А что имеется в виду под не управляемым кодом? Если это не скрипт, а какой-нибудь бинарник на C++, то использовать там компоненты из .NET возможно (будет mixed-сборка, где часть кода нативного, а часть - управляемого).

      1. Так и делаю. Пишу сборку на C# (ActiveX/COM) которая по сути открывает то что закрыто. И главное это все работает!
        Под неуправляемым кодом понимается приложение писаное на C++. Так и получается микс из управляемого и неуправляемого кода.
        Просто я думал MS про такую связку думали и возможно даже есть нормальный Bridge. Но я встречал только платные рукодельные мосты...

  10. Подскажите один момент, я вывел в эту форму , как в примере , но форме разместил не LinkLabel , а Label, но для Label не получается изменить размер шрифта. Это можно как то сделать?

    1. Не уверен. Создать объект шрифта вряд ли получится (System.Drawing.Font, потому что его конструкторы принимают аргументы, а через WScript.CreateObject передать аргументы в конструктор не получится, насколько я знаю). Переопределить свойство FontHeight у самого лейбла тоже, скорее всего, не сработает, вот что на этот счет написано в MSDN: "The FontHeight property should not be set to any value other than the control's Font.Height value, or -1.".

  11. Здравствуйте.
    Можно ли создать скрипт для вызова из контекстного меню в любой папке, чтобы в этой папке менялся тип группировки и сортировки файлов на заранее заданный? Если да - то как? Спасибо.

    1. Не уверен, что это возможно. Думаю, что без расширения для explorer'а тут не обойтись. Но так как я такие расширения не писал и не в курсе, как они работают, точно не скажу, можно ли использовать скрипты для их реализации.

  12. конечно интересный геморой, прикольно, годиться для мелких автоматизаций, а вот для серьёзных и сложных проектов нет. Проще скомпилить в Python скрипт с использованием eel

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *