Часть 7. Управление программами

Возможно, читая статьи о WSH, вы задавались вопросом: «Да что такого особенного в этом скрипте?». Действительно, править реестр можно и из reg-файлов, запускать программы, работать с сетевыми дисками, файлами и папками можно из bat-файлов. Да, WSH имеет более богатые возможности в этой области, работать с ним проще и удобнее, но стоят ли эти преимущества того, чтобы изучать данную тему? Для особо сомневающихся в этой статье я хочу затронуть такую область при работе на компьютере, где бессильны все остальные средства (за исключением специально написанных программ). А речь в ней пойдет о возможности управлять другими приложениями Windows (консольными приложениями для MS-DOS управлять не удастся).

В этот раз теории будет совсем немного, зато я постараюсь привести много очень любопытных примеров, ну, а дальше все будет зависеть от вашей фантазии.

Итак, что я подразумеваю под управлением другими приложениями? Активизацию существующего окна и имитацию нажатия в нем различных клавиш клавиатуры. Люди для этого пишут умные и сложные программы, а мы напишем простенький скрипт с тем же эффектом.

Начнем с того, что попытаемся активизировать окно уже запущенной программы.

//JScript
var WshShell = WScript.CreateObject("WScript.Shell");
WshShell.AppActivate("Блокнот");

Для активизиции окна мы воспользовались методом WshShell.AppActivate(). В качестве параметра передается какая-то текстовая строка. Скрипт осуществляет поиск окна, название которого эквивалентно переданной строке. Если такого окна нет, то будет вестись поиск окна, начало заголовка которого совпадает со строкой и в последнюю очередь ведется поиск окна, окончание заголовка которого эквивалентно переданной строке. Это очень удобно, т.к., например, в Word’e заголовок окна меняется в зависимости от имени редактируемого файла, но начало всегда «Microsoft Word». Если окон, удовлетворяющих условию поиска несколько, то активизируется первое найденное окно. Надо отметить, что если окно программы свернуто на панель задач, то оно не разворачивается, а просто кнопка приложения становится «нажатой».

Но просто сама по себе такая возможность мало что дает полезного, но вот в связке со следующим методом можно добиться потрясающего эффекта. И метод этот SendKeys(). Итак, давайте напишем небольшой забавный скрипт, позволяющий слегка посмеяться над друзьями:

//JScript
var WshShell = WScript.CreateObject("WScript.Shell");
KL = true;

while (KL) {
  if (WshShell.AppActivate("Блокнот")) {
    WriteWord();
    KL = false;
  }
  if (WshShell.AppActivate("Microsoft Word")) {
    WriteWord();
    KL = false;
  }
  WScript.Sleep(10000);
}

function WriteWord() {
WshShell.SendKeys("THE ");
WScript.Sleep(300);
WshShell.SendKeys("MATRIX ");
WScript.Sleep(300);
WshShell.SendKeys("HAS ");
WScript.Sleep(300);
WshShell.SendKeys("YOU...");
WScript.Sleep(300);
}

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

Вот похожий пример написанный на VBScript:

set WshShell = WScript.CreateObject("WScript.Shell")
KL = true

do while KL
  if WshShell.AppActivate("Microsoft Word") then
    WriteWord()
    KL = false
  end if
  WScript.Sleep 3000
loop

function WriteWord() 
WshShell.SendKeys "HELLO WORLD!"
end function

Я привел его для того, чтобы любители именно этого скриптового языка могли по аналогии переделать все остальные примеры в данной статье, потому что они будут на JScript.

Вынужден сразу разочаровать многих: русские буквы корректно в окно программы не передаются, так что придется обходиться только латинскими.

Помимо алфавитно-цифровых символов в приложения можно передавать и нажатие специальных клавиш, например, Enter, Tab, F1…F12, Alt, Shift, Ctrl, и т.п. В таблице приведены специальные обозначения для этих клавиш:

 

Клавиша Код Клавиша Код
«BackSpace» {BACKSPACE}, {BS} или {BKSP} «Break» {BREAK}
«Caps Lock» {CAPSLOCK} «F1″…»F12» {F1}…{F12}
«Delete» {DELETE} или {DEL} «End» {END}
«Enter» {ENTER} или ~ «Esc» {ESC}
«Help» {HELP} «Home» {HOME}
«Insert» {INSERT} или {INS} «Num Lock» {NUMLOCK}
«Page Down» {PGDN} «Page Up» {PGUP}
«Print Screen» {PRTSC} «Scroll Lock» {SCROLLLOCK}
«Tab» {TAB} «Стрелка вверх» {UP}
«Стрелка влево» {LEFT} «Стрелка вниз» {DOWN}
«Стрелка вправо» {RIGHT}

Для указания клавиш Alt, Shift, Ctrl существуют специальные коды:

 

Клавиша Код
Shift +
Ctrl ^
Alt %

Так если вы хотите передать нажатие нескольких клавиш с Shift-ом, то вам надо выполнять команду: WshShell.SendKeys(«+(ABC)»);, если только первую: WshShell.SendKeys(«+ABC»);.

Легко заметить, что такие символы как +, ^, % зарезервированы под обозначение специальных клавиш, так что просто так передать эти (и некоторые другие) символы не удастся. Для этого надо заключить их в фигурные скобки: «{+}», «{%}»… Вот полный список символов, которые необходимо заключать в фигурные скобки: +, ^, %, ~, (,), {, }, [, ].

Если вы хотите передать несколько нажатий подряд одной клавиши, то вам вовсе не обязательно все их набирать в скрипте, можно просто указать количество повторений. Так, строка WshShell.SendKeys(«{A 100}»); эквивалента сотне нажатий клавиши «А». Правда, есть ограничение на количество возможных повторений нажатия клавиш. Это значение лежит где-то между 8150 и 8180 раз (более точно мне было лень выяснять). При превышении этого значения в скрипте будет выдана ошибка.

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

var WshShell = WScript.CreateObject("WScript.Shell");
KL = true;

while (KL) {
  if (WshShell.AppActivate("Microsoft Word")) {
    WriteWord();
    KL = false;
  }
  WScript.Sleep(3000);
}

function WriteWord() {
WshShell.SendKeys("%{F4}");
WScript.Sleep(300);
WshShell.SendKeys("{TAB}");
WScript.Sleep(300);
WshShell.SendKeys("{ENTER}");
}

Комментировать не буду, итак все достаточно подробно объяснено по ходу статьи. Конечно, если вы не лишены гуманизма, то можно предварительно сохранить документ в какой-нибудь файл:

var WshShell = WScript.CreateObject("WScript.Shell");
KL = true;

while (KL) {
  if (WshShell.AppActivate("Microsoft Word")) {
    WriteWord();
    KL = false;
  }
  WScript.Sleep(3000);
}

function WriteWord() {
WshShell.SendKeys("%");
WScript.Sleep(300);
WshShell.SendKeys("{ENTER}");
WScript.Sleep(300);
WshShell.SendKeys("{DOWN}");
WScript.Sleep(300);
WshShell.SendKeys("{DOWN}");
WScript.Sleep(300);
WshShell.SendKeys("{DOWN}");
WScript.Sleep(300);
WshShell.SendKeys("{DOWN}");
WScript.Sleep(300);
WshShell.SendKeys("{ENTER}");
WScript.Sleep(300);
WshShell.SendKeys("test");
WScript.Sleep(300);
WshShell.SendKeys("{ENTER}");
}

Довольно забавно наблюдать, как пункт меню вдруг сам открывается, курсор перемещается по пунктам, а затем сохраняется документ. Конечно, проще было бы использовать «горячие» клавиши, но в русской версии это не пройдет (из-за некорректной передачи русских букв, о чем я уже писал выше), так что приходится выкручиваться таким способом, ну, а для английской версии легко переделать скрипт под использование «горячих» клавиш, что несколько сократит его размер.

Если вы помните, несколько лет назад был ажиотаж вокруг Spedia.net — спонсора платящего деньги за время, проведенное в интернете. Многие люди пытались на этом заработать, а учитывая тот факт, что некоторые провайдеры давали бесплатный доступ в ночное время, программеры начали писать утилитки, имитирующие работу пользователя за компьютером (запуск браузера, почтового клиента, серфинг по сайтам, получение почты и т.п.). Спедия по мере сил боролась с ними, блокируя оплату юзерам, использующим такие программы… Многим хотелось написать свою утилитку имитации работы, да еще чтобы ее не отловили, но для этого надо было знать программирование, причем там использовались не самые тривиальные знания. С помощью материала данной статьи, я думаю, теперь любой сможет написать нечто похожее :). Правда, сейчас это уже никому не нужно, но найти для полученных знаний более достойное применение вполне возможно.

   Отправить статью как PDF