Пожалуй, многие знают, что Windows начиная с версии 98 имеет по умолчанию в своем составе Windows Script Host (WSH), который позволяет исполнять скрипты на языках VBScript и JScript, но далеко не каждый хотя бы раз пользовался этой возможностью. В этой статье я приведу примеры полезных сниппетов и скриптов для WSH и попробую убедить вас в том, что вещь это действительно стоящая. Я также расскажу об очень занимательных и полезных возможностях WSH, о которых практически никто не знает, и информацию о которых в интернете найти весьма непросто.
Для начала немного о языках, поддерживающихся WSH. JScript — это, по сути, JavaScript с несколько измененной объектной моделью (например, в нем нет объекта window, как в браузерах, зато добавлен объект WScript, позволяющий взаимодействовать со средой, в которой исполняется скрипт). VBScript базируется на синтаксисе и возможностях Visual Basic 6 (и, возможно, более ранних версий). Оба языка имеют приблизительно одинаковые возможности. Кроме того, можно установить и другие языки для WSH, например, PerlScript, который, как вы уже догадались, базируется на Perl’е. Для этого следует воспользоваться, например, инсталлятором ActiveState Perl:
Крутые файлы BAT и VBS
В Windows по умолчанию расширение файла .js ассоциировано с JScript-скриптами, .vbs — с VBScript. При установке PerlScript появляется ассоциация .pls — с PerlScript-скриптами. Скрипты js и vbs можно закодировать с помощью утилиты от Microsoft screnc.exe, получив на выходе файл с расширением .jse или .vbe, соответственно. К сожалению, такое кодирование защитит лишь от неопытных пользователей — множество раскодировщиков можно найти в Google. Кроме того, при закодировании бывают проблемы с русским текстом.
Function WSHInputBox ( Message , Title , Value )
WSHInputBox = InputBox ( Message , Title , Value )
End Function
//Ваш код на JS
var name = WSHInputBox ( «Введите ваше имя:» , «Запрос» , «Вася Пупкин» ) ;
WScript . Echo ( «Имя: » + name ) ;
Таким же образом можно скомбинировать, например, JScript и PerlScript, если PerlScript у вас установлен:
use strict ;
our $ WScript ;
use LWP: : UserAgent ;
sub do_request
my $ lwp = new LWP: : UserAgent ;
my $ response = $ lwp -> get ( $ _ [ 0 ] ) ;
if ( $ response -> is_success )
return $ response -> headers -> as_string ;
return $ response -> error_as_HTML ;
WScript . Echo ( do_request ( «http://ya.ru» ) ) ;
Небольшое отступление — расскажу о запуске скриптов для WSH. По двойному клику мышкой они по умолчанию запускаются с помощью программы wscript.exe. В этом случае все вызовы WScript.Echo транслируются в обычные messagebox’ы. Если вы используете скрипт для автоматизации какого-либо процесса, например, сборки какого-либо проекта, и желаете выводить множество сообщений, то следует скрипт запускать с помощью программы cscript.exe, которая обращения к WScript.Echo транслирует в выводы в консоль. Запустить скрипт в консольном варианте можно, создав bat-файл с примерно таким содержимым:
Скинул WinLock школьнику + мамка
cscript my_script . wsf [ параметры ]
Можно также кликнуть на файле скрипта и вызвать меню «Open with command prompt».
Возможно, я кого-то удивлю, если скажу, что из скриптов для WSH можно с легкостью использовать классы .NET! Приведу пример на JScript (js-файл):
function vote_form ( )
//Создаем объект формы и всякие контролы
this . form = WScript . CreateObject ( «System.Windows.Forms.Form» ) ;
this . radioButton1 = WScript . CreateObject ( «System.Windows.Forms.RadioButton» ) ;
this . radioButton2 = WScript . CreateObject ( «System.Windows.Forms.RadioButton» ) ;
this . radioButton3 = WScript . CreateObject ( «System.Windows.Forms.RadioButton» ) ;
this . radioButton4 = WScript . CreateObject ( «System.Windows.Forms.RadioButton» ) ;
this . button1 = WScript . CreateObject ( «System.Windows.Forms.Button» ) ;
this . button2 = WScript . CreateObject ( «System.Windows.Forms.Button» ) ;
this . linkLabel1 = WScript . CreateObject ( «System.Windows.Forms.LinkLabel» ) ;
//Настраиваем контролы
with ( this . radioButton1 )
Parent = this . form ;
Checked = true ;
Width = 110 ;
Height = 17 ;
TabStop = true ;
Text = «VBScript» ;
with ( this . radioButton2 )
Parent = this . form ;
Width = 110 ;
Height = 17 ;
TabStop = true ;
Text = «JScript» ;
with ( this . radioButton3 )
Parent = this . form ;
Width = 110 ;
Height = 17 ;
TabStop = true ;
Text = «PerlScript» ;
with ( this . radioButton4 )
Parent = this . form ;
Width = 110 ;
Height = 17 ;
TabStop = true ;
Text = «Единая Россия» ;
with ( this . button1 )
Parent = this . form ;
Height = 23 ;
DialogResult = 1 ;
with ( this . button2 )
Parent = this . form ;
Height = 23 ;
Text = «Идите вы!» ;
DialogResult = 0 ;
with ( this . linkLabel1 )
Parent = this . form ;
Height = 15 ;
Text = «kaimi.io» ;
//настраиваем форму
with ( this . form )
Width = 222 ;
Height = 125 ;
Text = «Какой язык вам больше по душе?» ;
AutoSize = true ;
FormBorderStyle = 5 ; //FixedToolWindow
CancelButton = this . button1 ;
CancelButton = this . button2 ;
//Отобразить форму и вернуть true, если пользователь нажал на первую кнопку
this . show = function ( )
this . form . ShowDialog ( ) ;
return this . form . DialogResult == 1 ;
//Получить выбранный результат (см. выше, на форме 4 radio button’а)
this . result = function ( )
if ( this . radioButton1 . Checked )
return this . radioButton1 . Text ;
else if ( this . radioButton2 . Checked )
return this . radioButton2 . Text ;
else if ( this . radioButton3 . Checked )
return this . radioButton3 . Text ;
else if ( this . radioButton4 . Checked )
return this . radioButton4 . Text ;
//Создаем форму
var my_form = new vote_form ;
//Предлагаем пользователю сделать выбор
while ( true )
if ( my_form . show ( ) )
WScript . Echo ( «Вы выбрали: » + my_form . result ( ) ) ;
WScript . Echo ( «Ну как же так, надо же выбрать!» ) ;
Выполнив этот скрипт, увидим такую форму:
И все это создано с помощью .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 у вас не заработал (что, скорее всего, так и есть), наберите в консоли команду:
% WINDIR % Microsoft . NET Framework v2 . 0.50727 RegAsm . exe System . Windows . Forms . dll / codebase
либо, если вы пользуетесь 64-битной операционной системой, то
% WINDIR % Microsoft . NET Framework64 v2 . 0.50727 RegAsm . exe System . Windows . Forms . dll / codebase
Эта команда опубликует сборку 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.NETFramework64v2.0.50727, после чего зашел в неймспейс System и нашел класс Random в нем. Теперь ясно — если мы хотим воспользоваться методом Next, предоставляющим возможность указать минимальное и максимальное значение при генерации рандома, то следует вызвать Next_2 (так как этот метод второй с конца в списке методов Next, смотрите скриншот выше):
var random = WScript . CreateObject ( «System.Random» ) ;
WScript . Echo ( random . Next_2 ( 10 , 20 ) ) ; //выводим рандомное число в диапазоне от 10 до 20
Еще одной из интересных возможностей скриптов для 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. Работаем с файловой системой.
Источник: kaimi.io
VBS — Работа с программами при помощи WshShell
Перед началом работы, нам нужно создать его копию. Для этого, как и с FSO, мы создаём копию в переменную:
Set WshShell = CreateObject(«WScript.Shell»)
Теперь давайте посмотрим, что нам это даёт:
WshShell.CurrentDirectory — возвращает путь к текущей папке
Например, MsgBox WshShell.CurrentDirectory
- Текст — текст сообщения.
- СекОжидания — необязательный.Количество секунд, по истечении которого окно будет автоматически закрыто.
- — необязательный. Текст заголовка окна сообщения.
- — необязательный. Определяет тип кнопок и значка. Возможные значения флагов:
- 0 — кнопка ОК.
- 1 — кнопки ОК и Отмена.
- 2 — кнопки Стоп, Повтор, Пропустить.
- 3 — кнопки Да, Нет, Отмена.
- 4 — кнопки Да и Нет.
- 5 — кнопки Повтор и Отмена.
- 16 — значок Stop.
- 32 — значок Question.
- 48 — значок Exclamation.
- 64 — значок Information.
Возвращает целое значение, с помощью которого можно узнать, какая кнопка быля нажата пользователем. Возможные значения:
- -1 — таймаут.
- 1 — кнопка ОК.
- 2 — кнопка Отмена.
- 3 — кнопка Стоп.
- 4 — кнопка Повтор.
- 5 — кнопка Пропустить.
- 6 — кнопка Да.
- 7 — кнопка Нет.
В общем, данный метод схож с функцией msgbox.
WshShell.SendKeys «Кнока» — Послать нажатие кнопки Некоторые специальные символы следует всегда задавать заключёнными в фигурные скобки. Перечень таких символов: <(> <)> <[> <>>
Задание неотображаемых символов и специальных клавиш:
«» приведёт к нажатию клавиши 42 раза подряд
«» приведёт к нажатию клавиши 10 раз подряд.
Нажатие клавиш и при нажатом следует записывать как «+(GS)». Запись «+GS» приведёт к нажатию клавиши при нажатом , а затем клавиши уже без .
Источник: vbsabout.wordpress.com
Запустите vbscript из другого vbscript
Как мне получить vbscript для запуска другого vbscript?
Id представьте себе только несколько строк кода, но не пробовал делать это раньше, ничего не передается между 2, нужно просто вызвать/запустить другой.
В качестве примера запускаемый script называется TestScript.vbs, другой script для его вызова/запуска будет вызываться Secondscript.vbs, оба из которых расположены в C:Temp.
Лучший ответ:
Посмотрите, работает ли следующее
Dim objShell Set objShell = Wscript.CreateObject(«WScript.Shell») objShell.Run «TestScript.vbs» ‘ Using Set is mandatory Set objShell = Nothing
Чтобы завершить, вы можете отправить 3 аргумента следующим образом:
objShell.Run «TestScript.vbs 42 «»an arg containing spaces»» foo»
Вы можете попробовать использовать метод Wshshell.Run, который дает вам небольшой контроль над процессом, который вы начинаете с него. Или вы можете использовать метод WshShell.Exec, который даст вам возможность закончить его, получить ответ, передать больше параметров (кроме аргументов командной строки), получить статус и другие.
Чтобы использовать Run (простой метод)
Dim ProgramPath, WshShell, ProgramArgs, WaitOnReturn,intWindowStyle Set WshShell=CreateObject («WScript.Shell») ProgramPath=»c:test run script.vbs» ProgramArgs=»/hello /world» intWindowStyle=1 WaitOnReturn=True WshShell.Run Chr (34) Chr (34) ProgramArgs,intWindowStyle, WaitOnReturn
ProgramPath – это полный путь к вашему script, который вы хотите запустить.
ProgramArgs – это аргументы, которые вы хотите передать в script. (ПРИМЕЧАНИЕ: аргументы разделяются пробелом, если вы хотите использовать аргумент, содержащий пробел, тогда вам придется заключить этот аргумент в кавычки. [Безопасный способ сделать это – использовать CHR (34) Пример ProgramArgs= chr (34) /Hello World» WScript.Shell») ProgramPath=»c:test run script.vbs» ProgramArgs=»/hello /world» ScriptEngine=»CScript.exe» Set Process=WshShell.Exec (ScriptEngine Chr(34) Chr (34) ProgramArgs) Do While Process.Status=0 ‘Currently Waiting on the program to finish execution. WScript.Sleep 300 Loop
ProgramPath, аналогично Run READ RUN DESCRIPTION
ProgramArgs DITTO
ScriptEngine Двигатель, который вы будете использовать для выполнения script. поскольку для метода exec требуется приложение win32, вам необходимо указать это. Обычно либо “WScript.exe”, либо “CScript.exe”
Процесс – это объект, который ссылается на программу, начинающуюся с script. Он имеет несколько членов, и они: ExitCode, ProcessID, Status, StdErr, StdIn, StdOut, Terminate.
Подробнее о членах объекта процесса
- ExitCode. Это код выхода, который возвращается при завершении процесса.
- ProcessID. Это идентификатор, назначенный процессу, каждый процесс имеет уникальный идентификатор processID.
- Статус. Это код, который указывает статус процесса, после завершения процесса он получает значение “-1”.
- StdErr Это объект, который представляет стандартный поток ошибок
- StdIn. Это объект, который представляет стандартный поток ввода, использует его для записи дополнительных параметров или всего, что вы хотите передать в script, который вы используете. ( Process.StdIn.WriteLine «Hello Other Worlds» )
- StdOut. Это объект, представляющий стандартный поток вывода. Он READONLY, поэтому вы можете использовать Process.StdOut.ReadLine Если читать нечего, тогда script будет зависать, ожидая выхода, что означает, что script будет не отвечать
- Terminate Вызовите этот метод, чтобы принудительно завершить процесс.
Для получения дополнительной информации о WshShell.Exec перейдите в Exec Method Windows Scripting Host
Вы также можете загрузить тело script и выполнить его в рамках одного процесса:
Set fs = CreateObject(«Scripting.FileSystemObject») Set ts = fs.OpenTextFile(«script2.vbs») body = ts.ReadAll ts.Close Execute body
Option Explicit On error resume next Dim Shellobj Set Shellobj = CreateObject(«WScript.Shell») Shellobj.Run «Test.vbs» Set Shellobj = Nothing
Если вы не хотите злиться на пробелы в аргументах и хотите использовать переменные, попробуйте это:
objshell.run «cscript «»99 Writelog.vbs»» /r:» » /f:»»» «»» /c:»»» «»
r=123 c=»Whatever comment you like»
Я видел, как работает код ниже.
Простой, но, я думаю, не документировано.
Кто-нибудь еще использовал команду “Выполнить”?
Dim body, my_script_file Set Fso = CreateObject(«Scripting.FileSystemObject») Set my_script_file = fso.OpenTextFile(FILE) body = my_script_file.ReadAll my_script_file.Close Execute body
Как Ответ Мартина не работал вообще для меня ( “Файл не найден” ) и atesio Answer не позволяет вызывать два сценария, которые включают в себя повторяющиеся определения переменных, вот еще одна альтернатива, которая в конечном итоге помогла мне:
filepath = Chr(34) C:. helloworld.vbs» WScript.Shell») objshell.Run «wscript » https://techarks.ru/qa/zapustite-vbscript-iz-drugog-WM/» target=»_blank»]techarks.ru[/mask_link]