Сегодня уже многие забыли про VBScript (Visual Basic Script, он же VBS). А зря. Это достаточно простой язык программирования (с моей точки зрения он проще, чем раскрученный ныне Python), который позволяет легко и быстро создавать сценарии. VBS — язык написания сценариев для выполнения как на WEB странице (сервере), так и локально на компьютере. Особенно он может быть полезен для системных администраторов для выполнения рутинных задач.
В отличие, например, от Python, для выполнения сценариев на VBScript не требуется установки никаких дополнительных программ. А для написания кода на VBScript в большинстве случаев не требуется подключать, и тем более устанавливать дополнительные библиотеки. В Python это раздражает.
В отличие от JavaScript, VBS намного проще. Кроме того, Windows сценарии на JavaScript без дополнительных извращений выполнить нельзя, потому что предустановленный Windows Script Host (WSH), который используется в Windows для выполнения сценариев, не поддерживает язык JavaScript. Он поддерживает JScript — очень похожий, но всё-таки другой язык.
Если есть возможность использовать варианты с cmd или bat файлами — лучше использовать их. Меньше вероятность получить где-то ошибку.
Mexanik
З а ч н ё м )))
В VBS работают следующие правила:
- длина строки не ограничена;
- регистр символов не учитывается;
- количество пробелов между параметрами не учитывается;
- строку команды можно разрывать, а на месте разрыва нужно вставлять символ » _ «;
- максимальная длина имени переменной 255 символов;
- комментарии обозначаются сиволом » ‘ «.
Рекомендуемая структура сценария:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
' === Script Information Header === ' Script Name: ' название сценария; ' Date: ' дата изменения; ' Author: ' автор; ' Description: ' описание; ' === Initialization Block === Option Explicit ' директива, запрещающая автоматическое создание ' переменных; Dim <Variable> ' объявление переменных; Dim <Array>() ' объявление массивов; Set <Object> ' подключение объектов; ' === Script Main Logic === ' тело сценария; ' === Functions and Procedures === ' процедуры и функции; |
Объявление переменных, констант и массивов
В VBS есть глобальные и локальные переменные, доступные только в конкретной области.
|
1 2 3 |
Dim Variable1 ' объявление глобальной переменной Public Variable2 ' объявление глобальной переменной Private Variable3 ' объявление локальной переменной |
Использование Public и Private по большей части имеют смысл при использовании классов в VBS, которые будут рассмотрены в следующей статье. В языке VBS так же можно объявить константы:
|
1 |
Const Const1 = Value1 |
Переменную так же можно вообще не объявлять, а сразу присваивать ей значение, однако, так делать не рекомендуется, т.к. в случае опечатки в названии переменной, можно получить не те результаты, что ожидались. Чтобы компилятор требовал явного объявления всех переменных, нужно использовать оператор Option Explicit
Тип переменной задается при присвоении ей значения, при этом тип может меняться в процессе выполнения программы.
Массивы объявляются с помощью скобок.
|
1 2 3 |
Dim Arr1(10) ' Объявление массива с фиксированным размером (11 элементов) Dim Arr2() ' Объявление динамического массива ReDim Preserve Arr2(100) ' Изменение размера динамического массива |
Как и с переменными, тип массива задается при присвоении значения, причем, у разных элементов массива могут быть разные типы.
Очистить массив от данных можно так:
|
1 |
Erase имя_массива |
Константы объявляются в начале сценария с помощью конструкции:
|
1 2 3 4 |
Const <ConstName1> = <Value1> ' константа, доступная всем подпрограммам; Public Const <ConstName2> = <Value2> ' константа, доступная всем подпрограммам; Private Const <ConstName3> = <Value3> ' константа, доступная только текущей ' программе и ее подпрограммам. |
Данные можно проверять на соответствие типам, а так же переводить из одного типа в другой, если значения позволяют это сделать. Для операций над типами данных используются следующие команды:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
VarType(<Value>) ' возврат номера типа переменной; TypeName(<Value>) ' возврат имени типа переменной; IsArray(<Value>) ' проверка, что переменная - это массив; IsDate(<Value>) ' проверка, что переменная - это дата; IsEmpty(<Value>) ' проверка, что переменная неинициализирована; IsNull(<Value>) ' проверка, что переменная пустая; IsNumeric(<Value>) ' проверка, что переменная - это число; IsObject(<Value>) ' проверка, что переменная - это объект; CCur(<Value>) ' конвертация в тип currency; CBool(<Value>) ' конвертация переменной в тип boolean; CByte(<Value>) ' конвертация переменной в тип byte; CDate(<Value>) ' конвертация переменной в тип date; CDbl(<Value>) ' конвертация переменной в тип double; CInt(<Value>) ' конвертация переменной в тип integer; CLng(<Value>) ' конвертация переменной в тип long; CSng(<Value>) ' конвертация переменной в тип single; CStr(<Value>) ' конвертация переменной в тип string. |
Как было сказано выше, Visual Basic не накладывает строгих ограничений на имена переменных, но в то же время существуют рекомендации для названий переменных, чтобы в тексте сценария легко определять тип данных. Для этого перед именем переменной рекомендуется ставить условные символы, которые определяют тип переменной:
- iValueName — числовые типы
- sValueName — строковый тип
- bValueName — логический тип
- dValueName — дата
- oValueName — объект
- cValueName — константа
- aArrayName — массив
Ветвления по условию
Ни один полноценный сценарий не обходится без ветвлений, ветвления помогают выбрать верный путь при выполнении или невыполнении какого-то заложенного условия. Иными словами, ветвления реализуют логику сценария. В VBS-сценариях реализованы несколько механизмов ветвлений. Рассмотрим их по порядку.
Конструкция для одного действия, выполняемого по условию:
|
1 |
If <Condition> Then <Action> |
Конструкция для нескольких действий, выполняемых по условию:
|
1 2 3 4 |
If <Condition> Then <Action> <Action> End if |
Конструкция «развилка»:
|
1 2 3 4 5 6 7 |
If <Condition> Then <Action> <Action> Else <Action> <Action> End if |
Конструкция «развилка на несколько путей» (вариант сIf):
|
1 2 3 4 5 6 7 8 9 10 |
If <Condition> Then <Action> <Action> ElseIf <Condition> Then <Action> <Action> Else <Action> <Action> End if |
Во всех приведенных выше конструкциях применяется следующее правило: «Если выполняется условие <Condition>, то произвести список действий <Action>, которые расположеные под текущем блоком условия. Если текущее условие не выполняется, то перейти к списку действий <Action> под командой Else.»
Конструкция «развилка на несколько путей» (вариант сSelect):
|
1 2 3 4 5 6 7 8 9 10 11 |
Select Case <Variable> Case <Significance> <Action> <Action> Case <Significance> <Action> <Action> Case Else <Action> <Action> End Select |
В данной конструкции работает правило: «Если значение переменной <Variable> равно значению <Significance>, то произвети список действий <Action> под этим значением, иначе перейти к проверке следующего значения <Significance>.»
Циклы
Для организации повторяющихся действий или перебора элементов массива обычно используются циклы. В VBS-сценариях организованы несколько видов циклов: обычный цикл, цикл с неизвестным количеством итераций, цикл по условию.
Обычный цикл организуется структурой For — Next, в аргументах которой задаются такие параметры как имя счетчика (<Counter>), начальное значение счетчика (<Start>), конечное значение счетчика (<Finish>) и, при необходимости, шаг счетчика (Step <StepSize>).
|
1 2 3 |
For <Counter> = <Start> To <Finish> [Step <StepSize>] <Actions> Next |
Если в процессе работы цикла потребуется прекратить перебор значений, то это можно сделать с помощью команды Exit For.
|
1 2 3 4 5 |
For <Counter> = <Start> To <Finish> <Actions> If <Condition> Then Exit For <Actions> Next |
Цикл с неизвестным количеством итераций обычно применяется для перебора всех значений в коллекции объекта, когда не известна его размерность. Эта структура переберет все значения (<Variable>) массива, переданного как парамер цикла (<Array>).
|
1 2 3 |
For Each <Variable> In <Array> <Actions> Next |
Пример.
|
1 2 3 |
For Each oCurrentFile In oFiles WScript.Echo oCurrentFile.Name Next |
Циклы с условиями применяются для обработки данных, при выполнении какого-то условия. Такие циклы бывают двух видов: с проверкой в начале цикла и с проверкой в конце.
Цикл, пока выполняется условие, с проверкой в начале
|
1 2 3 |
Do While <Condition> <Action> Loop |
Цикл, пока не выполнится условие, с проверкой в начале
|
1 2 3 |
Do Until <Condition> <Action> Loop |
Как уже было сказано выше, условия можно ставить в конец цикла. В этом случае тело цикла будет выполнено как минимум один раз. Так же как и в обычных циклах, цикл с условием можно прервать командой Exit Do:
|
1 2 3 4 5 |
Do <Action> If <Condition> Then Exit Do <Action> Loop Until <Condition> |
Встроенные функции
Чтобы работать с данными и строить свои процедуры и функции, разработчки Visual Basic уже позаботились об основе сценариев — базовых функциях. VBS-скрипты функции для работы с датами, строками и числами, а так же базовые процедуры ввода-вывода и процедуры работы с сетью. Давайте вкратце рассмотрим встроенные функции.
Функции обработки дат:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
Date ' возврат текущей даты; Time ' возврат текущего времени; Now ' возврат текущих даты ' и времени; DateDiff(<Interval>, <Date1>, <Date2>) ' возврат разницы между ' датами; MonthName(<MonthNumber>) ' возврат названия месяца; WeekDayName(<Day>, <Abbreviation>, <FirstDayOfWeek>) ' возврат названия дня недели; Day(<Date>) ' возврат дня из указанной ' даты; Month(<Date>) ' возврат месяца из указанной ' даты; Year(<Date>) ' возврат года из указанной ' даты; Hour(<Date>) ' возврат часа из указанной ' даты; Minute(<Date>) ' возврат минуты из указанной ' даты; Second(<Date>) ' возврат секунды из указанной ' даты. |
Функции обработки строк:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
Asc(<Char>) ' возврат ANSI-кода символа; Chr(<Number>) ' возврат символа по ANSI-коду; InStr(<Line>, <Find>) ' возврат позиции подстроки в ' указанной строке; InStrRev(<Line>, <Find>) ' возврат позиции подстроки ' в указанной строке, начиная ' с конца строки; Join(<Array>, <Delimiter>) ' преобразование массива в строку; Len(<Line>) ' возврат длины строки; LCase(<Line>) ' преобразование строки в строку ' из малых символов; UCase(<Line>) ' преобразование строки в строку ' из больших символов; Left(<Line>, <Number>) ' возврат указанного количества ' символов с начала строки; Right(<Line>, <Number>) ' возврат указанного количества ' символов с конца строки; Mid(<Line>, <StartNumber>, <Number>) ' возврат указанного количества ' символов суказанного номера ' символа строки; Replace(<Line>, <Find>, <Replace>[, Params]) ' замена подстроки в указанной ' строке; Space(<Number>) ' строки из указанного количества ' пробелов; Split(<Line>, <Delimiter>[, Params]) ' преобразование строки в массив; String(<Number>, <Char>) ' строка из указанного количества ' определенных символов; SrtReverse(<Line>) ' зеркальное отображение строки; Trim(<Line>) ' обрезка пробелов слева и справа ' от строки; LTrim(<Line>) ' обрезка пробелов слева от строки; RTrim(<Line>) ' обрезка пробелов справа от строки. |
Математические функции:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
Randomize ' инициализация механизма случайных чисел (ничего не возвращает); Rnd ' возврат случайного нецелочисленного значения от 0 до 1; Atn(<Number>) ' вычисление арктангенса числа; Cos(<Number>) ' вычисление косинуса числа; Sin(<Number>) ' вычисление синуса числа; Exp(<Number>) ' вычисление натурального логарифма числа; Log(<Number>) ' вычисление десятичного логарифма числа; Sqr(<Number>) ' вычисление квадратного корня числа; Abs(<Number>) ' вычисление абсолютного значения числа; Hex(<Number>) ' вычисление шеснадцатеричного значения числа; Int(<Number>) ' округление числа; Fix(<Number>) ' вычисление целой части числа. |
И, естественно, помимо упомянутых функций, сценарии поддерживают все простейшие математические и логические операции:
- = — оператор присваивания;
- + — сумма двух чисел;
- — — вычитание двух чисел;
- * — умножение двух чисел;
- / — деление двух чисел;
- \ — целочисленное деление двух чисел;
- Mod — остаток от деления двух чисел;
- ^ — возведение в степень;
- & — соединение двух строк;
- Is — сравнение двух объектов;
- Eqv — сравнение двух выражений;
- Not — логическая операция отрицания;
- And — логическая операция конъюнкции;
- Or — логическая операция дизъюнкции;
- Xor — логическая операция исключения;
- Imp — логическая операция импликации.
Очередность выполнения операций определяется как и во всех языках программирования: сначала выполняются операции в скобках, потом вычисляются функции, потом операции умножения и деления, следом идут сложение и вычитание, и завершают вычисление логические операции.
Пользовательские функции
Сценарии, написанные на Visual Basic, позволяют определять пользовательские процедуры и функции и вызывать их из основной программы. Между процедурой и функцией практически нет никакого различия, разница заключется в логическом смысле этих подпрограмм: функции обычно используются для вычисления какого-то значения, а процедуры — для выполнения действий. Тем не менее и процедуры, и функции могут выполнять операции и передавать значения основной программе. Несмотря на это, все же не стоит забывать о предназначении этих подпрограмм: функции — для вычисления, процедуры — для действий.
Функция объявляется оператором Function, после которого следует название пользовательской функции, которое не должно совпадать ни с одним зарезервированным словом языка Visual Basic, далее указываются переменные, которые будут передаваться подпрограмме в качестве параметров — указание переменных в этой конструкции означает выделение ячеек памяти для переменных подпрограммы (объявление переменных для функции). В теле подпрограммы структура сценария ничем не отличается от обычной программы (здесь можно объявлять дополнительные переменные, поизводить операции, использовать другие функции и процедуры), в конце тела должен присутствовать оператор присвоения функции какому-то значению — это значение и будет возвращено основной программе. Прервать выполнение функции можно оператором Exit Function, но в этом случае нужно не забыть присвоить функции какое-то значение, иначе сценарий выдаст ошибку. Завершается функция оператором End Function.
Определение функции
|
1 2 3 4 5 6 7 8 9 10 |
Function <FunctionName>([Arguments]) <Actions> If <Condition> Then <Actions> <FunctionName> = <Value> Exit Function End If <Actions> <FunctionName> = <Value> End Function |
Вызов функции
|
1 |
<Variable> = <FunctionName>([Arguments]) |
Кстати, процедуры и функции должны располагаются в конце сценария.
Во время работы подпрограммы значения переменных основной части скрипта не изменяются, даже если в подпрограмме есть одноименные переменные. Чтобы подпрограмма имела возможность менять значения переменных основного сценария, необходимо в аргументах подпрограммы задать свойство переменных как ByRef. По умолчанию все переменные определяются со свойством ByVal.
|
1 2 3 4 5 |
Sub <SubName>(ByRef <Argument1>[, arguments]) <Actions> <Argument1> = <expression> <Actions> End Sub |
В данном случае аргумент <Argument1> передается по ссылке на ячейку памяти — меняется значение переменной в основном сценарии. Иными словами, с помощью параметра ByRef процедура превращается в функцию — подпрограмма возвращает результат вычислений в основную программу.
Обработка ошибок выполнения сценария
По умолчанию все ошибки обрабатываются сценарием в автоматическом режиме, и, при возникновении ошибки, работа сценария останавливается. Для отключения автоматической обработки ошибок нужно использовать специальную директиву On Error Resume Next, которая отключает автоматическую обработку ошибок и продолжает работы сценария даже при их наличии. Для ручной обработки ошибок необходимо обратится к встроенному объектуErr, который хранит в себе статус ошибок. Объект Err имеет следующие свойства и методы:
|
1 2 3 4 |
Number ' возврат номера последней ошибки; Description ' возврат описания последней ошибки; Clear ' очистка объекта Err; Raise ' вызов тестовой ошибки. |
Пример ручной обработки ошибки:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
On Error Resume Next iTotalPoints = InputBox("Введите общее количество очков") iNumberOfTests = InputBox("Введите количество тестов") iAvarage = iTotalPoints / iNumberOfTests Select Case Err.Number Case 0 ' нет ошибок; WScript.Echo "Средний балл = " & CStr(iAvarage) Case 11 ' деление на ноль; WScript.Echo "Количество тестов не может равняться нулю" Case 13 ' несоотвествие типов; WScript.Echo "Вы ввели нечисловое значение" Case Else ' нет ошибок; WScript.Echo "Неизвестная ошибка WScript.Quit" End Select |
Методы и свойства корневого класса WScript
Методы и свойства корневого класса WScript, не требуют создания объекта — они автоматически доступны для использования непосредственно в теле сценария.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
CreateObject(<Library>.<Class>) ' создание объекта; GetObject(<FilePath>) ' подключение объекта из файла; ConnectObject(<Object>, <Prefix>) ' подключение к событиям существующего объекта; DisconnectObject(<Object>) ' отключение от событий объекта; Echo([Message]) ' вывод сообщения на экран; Arguments ' возврат массива аргументов командной строки; Name ' возврат имени интерпретатора сценариев; Path ' возврат пути к интерпретатору сценариев; FullName ' возврат полного имени интерпретатора сценариев; Version ' возврат версии интерпретатора сценариев; BuildVersion ' возврат версии сборки интерпретатора сценариев; ScriptName ' возврат имени файла сценария; ScriptFullName ' возврат полного имени файла сценария; Interactive ' установка или возврат режима интерактивности; Sleep(<Milliseconds>) ' приостановка работы на указанное количество ' миллисекунд; Quit ' прекращение работы сценария. |
Методы и свойства класса Shell
Для работы с операционной системой используется специальный класс Shell, который позволяет выполнять такие операции как запуск программ, изменение реестра, создание ярлыков, доступ к системным папкам и системным переменным, доступ к системному журналу. Итак, методы и свойства класса Shell:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
ExpandEnvironmentStrings(<VariableName>) ' возврат значения запрошенной переменной системы; EnviEnvironment(<VariableName>) ' возврат массива переменных системы; CreateShortcut(<PathToCreate>) ' создание ярлыка; Popup(<Message>[, Params]) ' вывод оконного сообщения на экран; RegRead(<ValuePath>) ' считывание значения из реестра; RegWrite(<ValuePath>,<Value>[, Type]) ' запись значения в реестр; RegDelete(<ValuePath>) ' удаление значения из реестра; LogEvent(<Type>,<Message>) ' запись события в системный журнал; Run(<Command>[, Params]) ' запуск программы в новом процессе; Exec(<Command>) ' запуск программы в дочерней консоли; AppActivate(<Title>) ' активация окна; SendKeys(<Keys>) ' отправка символов в активное окно; CurrentDirectory ' установка или возврат текущей директории; SpecialFolders([FolderName]) ' возврат массива служебных папок или пути ' запрошенной служебной папки. |
Пример. Использование методов и свойств класса Shell.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
' Создание объекта класса Shell Set oShell = Wscript.CreateObject("WScript.Shell") ' Запуск калькулятора oShell.Run("Calc.exe") ' Задержка WScript.Sleep(100) ' Запуск блокнота oShell.Run("Notepad.exe") ' Задержка WScript.Sleep(100) ' Переключение на окно калькулятора oShell.AppActivate "Calculator" ' Задержка WScript.Sleep(100) ' Иммитация нажатия клавиш oShell.SendKeys("1{+}2{=}") ' Получение пути к рабочему столу sDesktopPath = oShell.SpecialFolders("Desktop") ' Создание объекта ярлыка Set oLink = oShell.CreateShortcut(sDesktopPath & "\Test.lnk") ' Настрока ярлыка oLink.TargetPath = WScript.ScriptFullName oLink.WindowStyle = 1 oLink.Hotkey = "CTRL+SHIFT+T" oLink.IconLocation = "notepad.exe,0" oLink.Description = "Test link" oLink.WorkingDirectory = sDesktopPath oLink.Save ' Создание объекта среды и получение в него свойств системы Set oSysEnv = oShell.Environment("SYSTEM") ' Вывод сообщения о количестве процессоров на экран MyResult = oShell.Popup("Number of processors: " & oSysEnv("NUMBER_OF_PROCESSORS"), _ 3, "Message", 0) ' Получение пути к папке Windows и вывод сообщения на экран MyResult = oShell.Popup("Windows directory: " & _ oShell.ExpandEnvironmentStrings("%WINDIR%"), 3, "Message", 0) ' Чтение ключа реестра и вывод его значения на экран WScript.Echo oShell.RegRead ("HKLM\Software\Microsoft\Windows\CurrentVersion\ProductID") ' Запись строкового значения в реестр MyResult = oShell.RegWrite("HKCU\ScriptEngine\Value", "My Value") ' Запись числового значения в реестр MyResult = oShell.RegWrite("HKCU\ScriptEngine\Key", 1, "REG_DWORD") ' Удаление ключа реестра MyResult = oShell.RegDelete("HKCU\ScriptEngine\") ' Запись события в системный журнал MyResult = oShell.LogEvent(0, "Test Script Completed") |
Методы и свойства класса Network
Как мы уже убедились, VBS-сценарии могут работать с оболочкой Windows, но это не единственная их возможность. С помощью класса Network можно получить доступ к сетевым объектам и управлять ими. Давайте подребнее разберем класс Network:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
ComputerName ' возврат имени компьютера; UserDomain ' возврат имени домена; UserName ' возврат имени пользователя; EnumNetworkDrives ' возврат списка подключенных сетевых дисков; MapNetworkDrive(<LocalName>, <RemoteName>, [UpdateProfile, User, Password]) ' подключение сетевого ресурса; RemoveNetworkDrive(<Name>, [Force], [UpdateProfile]) ' отключение сетевого ресурса; EnumPrinterConnections ' возврат списка сетевых принтеров; AddWindowsPrinterConnection(<PrinterPath>) ' подключение сетевого принтера; AddPrinterConnection(<LocalName>, <RemoteName>[, UpdateProfile, User, Password] ' подключение сетевого принтера на указанный порт; RemovePrinterConnection(<Name>[,Force, UpdateProfile]) ' отключение сетевого принтера; SetDefaultPrinter(<PrinterName>) ' выбор принтера по умолчанию; |
Пример. Использование методов и свойств класса Network.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
' Создание объекта класса Network Set oNetwork = WScript.CreateObject("WScript.Network") ' Вывод сообщения об имени компьютера WScript.Echo "Computer Name = " & oNetwork.ComputerName ' Вывод сообщения об имени текущего пользователя WScript.Echo "User Name = " & oNetwork.UserDomain & "\" & oNetwork.UserName ' Подключение сетевого диска oNetwork.MapNetworkDrive "Z:" "\\Server\Share" ' Получение коллекции подключенных сетевых дисков Set oDrives = oNetwork.EnumNetworkDrives ' Вывод сообщений о подключенных сетевых дисках For i=0 To oDrives.Count -1 step 2 WScript.Echo "Drive " & oDrives.Item(i) & " = " & oDrives.Item(i+1) Next ' Удаление сетевого диска oNetwork.RemoveNetworkDrive "Z:" ' Подключение сетевого принтера oNetwork.AddPrinterConnection "LPT1", "\\Server\Printer" ' Установка принтера по умолчанию oNetwork.SetDefaultPrinter "\\Server\Printer" ' Получение коллекции о подключенных принтерах Set oPrinters = oNetwork.EnumPrinterConnections |
Методы и свойства класса FileSystemObject
Очень часто в сценариях встречаются такие случаи, когда необходимо что-то создать, удалить, переместить или изменить на диске компьютера. Эту задачу позволяет решить класс FileSystemObject, предназначенный для работы с файловой системой. Ниже перечисленны объекты, которые может создать этот класс:
- FileSystemObject — главный объект, который позволяет создавать, удалять, управлять дисками, папками и файлами в общем;
- Drive — объект, позволяюший собирать информацию о дисках системы;
- Drives — объект, хранящий в себе список дисков системы;
- Folder — объект, позволяющий создавать, удалять, перемещать папки, а также собирать информацию о них и их содержимом;
- Folders — объект, хранящий в себе список подпапок указанной папки;
- File — объект, позволяющий создавать, удалять, перемещать файлы, а также собирать информацию о них;
- Files — объект, хранящий в себе список файлов указанной папки;
- TextStream — объект, позволяющий читать и создавать текстовые файлы.
Методы и свойства класса FileSystemObject (главного объекта):
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
BuildPath(<Path>, <Name>) ' добавляет имя к указанному ' пути; GetAbsolutePathName(<PathSpec>) ' возвращает полный путь; GetBaseName(<Path>) ' возвращает имя папки или файла '(без расширения) в указанном ' пути; GetDrive(<DriveSpec>) ' создает объект Drive; GetDriveName(<Path>) ' возвращает имя диска в ' указанном пути; GetExtensionName(<Path>) ' возвращает расширение файла в ' указанном пути; GetFile(<FileSpec>) ' создает объект File; GetFileName(<PathSpec>) ' возвращает имя файла ' (без расширения) ' в указанном пути; GetFolder(<FolderSpec>) ' создает объект Folder; GetParentFolderName(<Path>) ' возвращает имя папки в ' котором хранится ' файл или папка по указанному ' пути; GetSpecialFolder(<FolderSpec>) ' создает объект Folder к ' указанной служебной папке; GetTempName ' возвращает случайно ' сгенерированное имя файла; DriveExists(<DriveSpec>) ' проверяет существование диска; FolderExists(<FileSpec>) ' проверяет существование папки; CopyFolder(<Source>, <Destination>[, Overwrite]) ' копирует папку; MoveFolder(<Source>, <Destination>) ' перемещает папку; DeleteFolder(<FolderSpec>[, Force]) ' удаляет папку; CreateFolder(<FolderName>) ' создает папку; FileExists(<Filespec>) ' проверяет существование файла; CopyFile(<Source>, <Destination>[, Overwrite]) ' копирует файл; MoveFile(<Source>, <Destination>) ' перемещает файл; DeleteFile(<FileSpec>[, Force]) ' удаляет файл; CreateTextFile(<FileName>[, Overwrite, UnioCode]) ' создает текстовый файл; OpenTextFile(<FileName>[, IOMode, Create, Format]) ' открывает текстовый файл для ' чтения или записи. |
Объекты Drives, Folders и Files класса FileSystemObject хранят в себе информацию о дисках, папках и файлах и, в основном, используюся для сбора информации о файловой системе. Они имеют только два свойства:
|
1 2 3 |
Count ' возвращает количество элементов в коллекции; Item(<ObjectName>) ' возвращает запись с указанным индексом из коллекции (не используется), ' для перебора элементов коллекции приметяется цикл For Each. |
Чтобы было более понятно, что же такое коллекция объектов, рассмотрим пример вывода на экран списка файлов корня диска C:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
' Создание объекта класса FileSystemObject Set oFSO = CreateObject("Scripting.FileSystemObject") ' Создание объекта Folder Set oFolder = oFSO.GetFolder("C:\") ' Получение коллекции файлов Set oFilesCollection = oFolder.Files ' Получение количества элементов в коллекции sResult = sResult & oFilesCollection.Count & " files in C:\" & vbCrLf ' Чтение атрибутов каждого файла из коллекции For Each oFile in oFilesCollection sResult = sResult & oFile.Name & vbTab sResult = sResult & oFile.Size & vbCrLf Next ' Вывод результата на экран MsgBox(sResult) |
Объект Drive предоставляет доступ к свойствам локального или сетевого диска:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
AvailableSpace ' возвращает размер свободного места на диске, доступного пользователю; DriveLetter ' возвращает букву диска; DriveType ' возвращает тип диска; FileSystem ' возвращает тип файловой системы диска; FreeSpace ' возвращает размер свободного места на диске; IsReady ' возвращает доступность диска; Path ' возвращает путь к диску; RootFolder ' создает объект Folder, указывающий на корень диска; SerialNumber ' возвращает серийный номер диска; ShareName ' возвращает сетевое имя диска; TotalSize ' возвращает емкость диска в байтах; VolumeName ' возвращает или устанавливает метку диска. |
Объект Folder предоставляет доступ ко всем свойствам папки, а также позволяет производить над ней действия:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
Attributes ' возвращает атрибуты папки; DateCreated ' возвращает дату создания папки; DateLastAccessed ' возвращает дату последнего доступа к папке; DateLastModified ' возвращает дату изменения папки; Drive ' возвращает букву диска, на котором расположена папка; Files ' возвращает коллекцию файлов папки; IsRootFolder ' возвращает True, если папка - это корень диска; Name ' возвращает имя папки; ParentFolder ' создает объект Folder, указывающий на ' родительскую папку; Path ' возвращает путь к папке; ShortName ' возвращает имя папки в формате 8.3; ShortPath ' возвращает путь к папке в формате 8.3; Size ' возвращает размер папки; SubFolders ' возвращает коллекцию подпапок; Type ' возвращает тип папки; Copy(<Destination>[, Overwrite]) ' копирует папку; Move(<Destination>) ' перемещает папку; Delete(<Force>) ' удаляет папку; CreateTextFile(<FileName>[, Overwrite, UniCode]) ' создает в папке текстовый файл. |
Объект File аналогичен объекту Folder — он предоставляет доступ ко всем свойствам файла, а также позволяет производить над ним действия:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Attributes ' возвращает атрибуты файла; DateCreated ' возвращает дату создания файла; DateLastAccessed ' возвращает дату последнего доступа к файла; DateLastModified ' возвращает дату изменения файла; Drive ' возвращает букву диска, на котором расположен файл; Name ' возвращает имя файла; ParentFolder ' создает объект Folder, указывающий на ' родительскую папку; Path ' возвращает путь к файлу; ShortName ' возвращает имя файла в формате 8.3; ShortPath ' возвращает путь к файлу в формате 8.3; Size ' возвращает размер файла; Type ' возвращает тип файла; Copy(<Destination>[, Overwrite]) ' копирует файл; Move(<Destination>) ' перемещает файл; Delete(<Force>) ' удаляет файл; OpenAsTextStream([IOMode, Format]) ' открывает текстовый файл для чтения или записи. |
Объект TextStream — это инструмент доступа к содержимому файла. С помощью него можно читать и изменять файл:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
AtEndOfLine ' показывает, достигнут ли конец строки; AtEndOfStream ' показывает, достигнут ли конец строки; Column ' возвращает номер колонки, в которой находится курсор ' 00чтения; Line ' возвращает номер строки, в которой находится курсор ' чтения; Close ' закрывает файл - освобождает его для других ' процессов; Read(<CharactersNumber>) ' считывает указанное количество символов, начиная ' от позиции ' курсора чтения; ReadAll ' считывает весь файл; ReadLine ' считывает строку, в которой находится курсор ' чтения; Skip(<CharactersNumber>) ' пропускает указанное количество символов, начиная ' от позиции ' курсора чтения; SkipLine ' пропускает строку, в которой находится курсор ' чтения; Write(<String>) ' записывает строку; WriteLine(<String>) ' записывает строку и переводит курсор записи на ' следующую строку; WriteBlankLines(<Lines>) ' записывает указанное количество пустых строк. |
Мы познакомились со всеми методами и свойствами класса FileSystemObject, рассмотрим пример использования этого класса:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
' Задание констант кодов системных папок Const WindowsFolder = 0 Const SystemFolder = 1 Const TemporaryFolder = 2 ' Задание констант кодов типов доступа к текстовому файлу Const ForReading = 1 Const ForWriting = 2 Const ForAppending = 8 ' Создание объекта класса FileSystemObject Set oFSO = CreateObject("Scripting.FileSystemObject") ' Получение коллекции дисков Set DrivesCollection = oFSO.Drives ' Обработка каждого диска для получения его метки или сетевого имени For Each oDrive in DrivesCollection sResult = sResult & oDrive.DriveLetter & ": " If oDrive.DriveType = Remote Then sResult = sResult & oDrive.ShareName & vbCrLf ElseIf oDrive.IsReady Then sResult = sResult & oDrive.VolumeName & vbCrLf Else sResult = sResult & vbCrLf End If Next ' Вывод результатов на экран Wscript.Echo(sResult) ' Создание объекта диска C: Set oDrive = oFSO.GetDrive("C") sResult = oDrive.DriveLetter & ": - " ' Получение типа диска C: Select Case oDrive.DriveType Case 0: sResult = sResult & "Unknown - " Case 1: sResult = sResult & "Removable - " Case 2: sResult = sResult & "Fixed - " Case 3: sResult = sResult & "Network - " Case 4: sResult = sResult & "CD-ROM - " Case 5: sResult = sResult & "RAM Disk - " End Select ' Определение доступности диска и получение его свойств If oDrive.IsReady Then sResult = sResult & "Ready" & vbCrLf sResult = sResult & "FileSystem is " & oDrive.FileSystem & vbCrLf sResult = sResult & "Available Space: " & _ FormatNumber(oDrive.AvailableSpace/1024, 0) & " Kbytes" Else sResult = sResult & "Not ready" End If ' Вывод результатов на экран Wscript.Echo(sResult) ' Создание объекта служебной папки (папка временных фалов Windows) Set oTempFolder = oFSO.GetSpecialFolder(TemporaryFolder) ' Создание объекта текстового файла (и создание его в корне диска C:) Set oFile = oFSO.CreateTextFile("C:\TestFile.txt", True) ' Запись в текстовый файл oFile.WriteLine("This is a test.") oFile.WriteLine(sResult) ' Закрытие текстового файла и освобождение его для других процессов oFile.Close ' Проверка на наличие файла в папке временных файлов Windows, удаление этого файла If oFSO.FileExists(oFSo.BuildPath(oTempFolder.Path, "TestFile.txt")) Then _ oFSO.DeleteFile(oFSo.BuildPath(oTempFolder.Path, "TestFile.txt")) ' Создание объекта файла Set oFile = oFSO.GetFile("C:\TestFile.txt") ' Перемещение файла в папку временных файлов Windows oFile.Move(oFSo.BuildPath(oTempFolder.Path, "TestFile.txt")) ' Изменение атрибута у файла If oFile.Attributes and 32 Then oFile.Attributes = oFile.attributes - 32 Wscript.Echo("Archive bit is cleared") Else oFile.Attributes = oFile.attributes + 32 Wscript.Echo("Archive bit is set") End If sResult = oFile.Path & vbCrLf & oFile.DateLastModified & ":" & vbCrLf ' Создание объекта потока путем открытие файла на чтение Set oTestFile = oFSO.OpenTextFile(oFile.Path, ForReading, False) ' Чтение потока, пока не встречен его конец Do While oTestFile.AtEndOfStream <> True sResult = sResult & oTestFile.ReadLine Loop ' Закрытие текстового файла и освобождение его для других процессов oTestFile.Close ' Вывод сообщения на экран Wscript.Echo(sResult) |
Сценарий «Удаление старых файлов»
Данный сценарий предназначен для очистки системы от устаревших файлов во временных каталогах Windows и профилях пользователей. В этом примере можно увидеть как работают практически все вышеописанные конструкции: структура сценария, название переменных, работа с массивами и коллекциями, ручная обработка ошибок, считывание системных переменных, создание текстового файла журнала работы сценария, работа с файловой системой, использование процедур.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
' ==== Script Information Header ==== ' script name: Purge Temp ' version: 1.0 ' date: 16.07.08 ' autor: Bochkarev Vitaly ' description: Скрипт удаляет устаревшие временные файлы с компьютера ' ==== Script Main Logic ==== ' Включение ручной обработки ошибок On Error Resume Next ' Константа временного интервала, когда файлы считаются устаревшими Const PurgeTime = 14 ' дней ' Исключения - профили пользователей, которые не должны обрабатываться Dim aExceptions(3) aExceptions(0) = "Default User" aExceptions(1) = "LocalService" aExceptions(2) = "NetworkService" aExceptions(3) = "All Users" ' Создание объектов оболочки и файловой системы Set oShell = CreateObject("wscript.shell") Set oFSO = CreateObject("Scripting.Filesystemobject") ' Определение путей служебных папок sProgramFiles = oShell.ExpandEnvironmentStrings("%ProgramFiles%") sWinDir = oShell.ExpandEnvironmentStrings("%WinDir%") sWinTempFolder = sWinDir & "\Temp" sDocuments = "C:\Documents and Settings" ' Создание фурнала работы сценария sLogFileName = sWinTempFolder & "\PurgeTemp_" & Date sLogFileName = Replace(sLogFileName, ".", "_") sLogFileName = Replace(sLogFileName, "/", "_") Set oLogFile = oFSO.CreateTextFile(sLogFileName & ".log",true) oLogFile.WriteLine "========== Start purging ==========" ' Очистка временной папки Windows oLogFile.WriteLine vbCrLf & "========== Windows Temporary folder ==========" PurgeFolder(sWinTempFolder) ' Очистка временной папки профиля пользователя и файлов Интернет oLogFile.WriteLine vbCrLf & _ "========== Users Temporary folder and Users Temporary Internet Files ==========" Set oDocuments = oFSO.GetFolder(sDocuments) Set colProfiles = oDocuments.SubFolders For Each oProfile In colProfiles bFlag = false For Each sException in aExceptions if InStr(oProfile.Path,sException) > 0 then bFlag = true exit for end if Next If bFlag = False Then PurgeFolder(oProfile.Path & "\Local Settings\Temp") PurgeFolder(oProfile.Path & "\Local Settings\Temporary Internet Files") End If Next ' Очистка карантина NOD32 oLogFile.WriteLine vbCrLf & "========== NOD32 Quarantine ==========" sQuarantine = sProgramFiles & "\Eset\Infected" PurgeFolder(sQuarantine) ' Закрытие файла журнала oLogFile.WriteLine vbCrLf & "========== Stop purging ==========" oLogFile.Close ' Процедура PurgeFolder - удаление старых файлов Sub PurgeFolder(sFolderPath) ' Создание объекта Folder Set oFolder = oFSO.GetFolder(sFolderPath) ' Получение коллекции файлов Set colFiles = oFolder.Files ' Обработка каждого файла из коллекции For each oFile in colFiles ' Проверка, является ли файл устаревшим If (Date-oFile.DateLastModified) > PurgeTime and (Date-oFile.DateCreated) > _ PurgeTime Then ' Запись сообщения в журнал сценария oLogFile.Writeline oFile.Path & vbTab & oFile.DateCreated ' Удаление устаревшего файла oFSO.DeleteFile oFile.Path, True ' Проверка на наличие ошибок if err.Number <> 0 then ' Запись сообщения об ошибке в журнал сценария oLogFile.Writeline "-----> Error # " & CStr(Err.Number) _ & " " & Err.Description ' Очистка ошибки Err.Clear end if ' Пауза в 20 милисекунд WScript.Sleep 20 End if Next ' Получение коллекции подпапок Set colSubFolders = oFolder.SubFolders ' Обработка каждой подпапки For Each oSubFolder In colSubFolders ' Рекурсивный вызов процедуры удаления старых файлов - подпрограмма вызывает ' сама себя PurgeFolder(oSubFolder.Path) ' Проверка размера папки If oSubFolder.Size = 0 Then ' Запись сообщения в журнал сценария oLogFile.Writeline oSubFolder.Path & vbTab & oSubFolder.DateCreated ' Удаление пустой папки oFSO.DeleteFolder oSubFolder.Path ' Проверка на наличие ошибок If err.Number <> 0 then ' Запись сообщения об ошибке в журнал сценария oLogFile.Writeline "-----> Error # " & CStr(Err.Number) _ & " " & Err.Description ' Очистка ошибки Err.Clear End if End if Next End Sub |
Итог использования сценариев таков:
- сценарии не требуют компиляции и их код в любой момент можно отредактировать;
- VBS-сценарии практически не ограничены в функциональности и могут использовать различные системные библиотеки и объекты других приложений;
- VBS-файлы могут выполняются как в консоли, так и в оконном режиме, поэтому пользователь может контролировать видимость хода выполнения сценария;
- VBS-сценарии позволяют использовать пользовательские процедуры и функции;
- этот язык идеально подходит для работы со строковыми и числовыми переменными, датами, а также для обработки текстовых файлов, управления системой и доменом;
- VBS-сценарии сложны в написании и требуют навыков программирования;
- такие сценарии работают только в операционных системах семейства Windows.