1 (изменено: kflirik, 2011-07-03 15:06:43)

Тема: AHK: Параллельное выполнение команд

Здравствуйте, существует ли возможно выполнять команды AHK параллельно? Например я запускаю 5 программ по очереди:

Game:= "Z:\mnt\misc\Games\WoW_3.3.5a\wow.exe -opengl"
PATH:= "Z:\mnt\misc\Games\WoW_3.3.5a\"

Run, %Game%, %PATH%, , instanceID1
sleep 2000
WinSetTitle, World of Wаrсrаft, ,WOW1
WinMove, ahk_pid %instanceID1%, , -0, -0, 1280, 1024
WinActivate, ahk_pid %instanceID1%
WinMaximize, ahk_pid %instanceID1%

Run, %Game%, %PATH%, , instanceID2
sleep 2000
WinSetTitle, World of Wаrсrаft, ,WOW2
WinMove, ahk_pid %instanceID2%, , 0, A_ScreenHeight-240, 320, 240

Run, %Game%, %PATH%, , instanceID3
sleep 2000
WinSetTitle, World of Wаrсrаft, ,WOW3
WinMove, ahk_pid %instanceID3%, , 320, A_ScreenHeight-240, 320, 240

Run, %Game%, %PATH%, , instanceID4
sleep 2000
WinSetTitle, World of Wаrсrаft, ,WOW4
WinMove, ahk_pid %instanceID4%, , 640, A_ScreenHeight-240, 320, 240

Run, %Game%, %PATH%, , instanceID5
sleep 2000
WinSetTitle, World of Wаrсrаft, ,WOW5
WinMove, ahk_pid %instanceID5%, , 960, A_ScreenHeight-240, 320, 240

Можно ли все блоки

Run, %Game%, %PATH%, ,
Sleep 2000
...

запустить параллельно? Если запускать без sleep, то WinSetTitle не срабатывает.
И еще вопрос, как указать программе выполняться на одном из ядер процессора? Это можно задать через параметры Run  или надо в строку запуска параметры какие то добавлять чтоб windows назначила ядра?

2

Re: AHK: Параллельное выполнение команд

Используйте

settimer

На счет ядер http://www.autohotkey.com/forum/topic8728-90.html, функция Affinity_Set()

3 (изменено: kflirik, 2011-07-03 16:17:55)

Re: AHK: Параллельное выполнение команд

Насчет

settimer

уже смотрел, не совсем понял. Я так понимаю мне надо создать 5 таймеров чтоб 5 задач запустились параллельно? И тогда насчет синтаксиса

SetTimer, Label [, Period|On|Off, Priority]

как сделать чтоб таймер сработал только 1 раз?

UPD: Если сделать запуск процессов по таймеру

SetTimer, RunWoW, 250
return

RunWoW:
Run, %Game%, %PATH%, ,
sleep 1500
WinSetTitle, World of Wаrсrаft, ,WOW5
return

то получается тоже самое как и по очереди, т.к. SetTimer ждет окончания работы после предыдущего запуска и невозможно присвоить окнам новые имена (везде одно).

4

Re: AHK: Параллельное выполнение команд

Settimer, Label, -1
return

msgbox Этот таймер запустится один раз

5

Re: AHK: Параллельное выполнение команд

InFlames, мне тоже интересно узнать, как SetTimer позволяет запускать команды параллельно.

Autohotkey help (RUS) пишет:

Хотя таймеры могут создать впечатление того, что скрипт выполняет несколько задач одновременно, это не так. Напротив, спланированная по времени подпрограмма ведет себя точно так же, как и любой другой поток: она может прервать какой-либо поток или быть прерванной другим потоком, например таким, как подпрограмма горячей клавиши.

kflirik, я думаю, Вам проще будет сначала выполнить 5 раз Run, %Game%, %PATH%, , instanceID. Затем подождать, пока все экземпляры приложения загрузятся, а потом уже всё остальное. Ведь Autohotkey не исполняет приложения, а только даёт короткую команду ОС на их запуск.
P. S. Если запускать несколько объёмных программ с одного жёсткого диска параллельно, времени уйдёт больше, нежели заупскать последовательно.

6 (изменено: kflirik, 2011-07-03 17:07:47)

Re: AHK: Параллельное выполнение команд

InFlames, согласен. Сделал запуски через SetTimer в итоге времени вышло практически одинаково (чуть быстрее).
Оставлю последовательный запуск.
SetTimer пожалуй мне все-же пригодится для одновременного ввода логинов/паролей в запущенные клиенты ))

UPD С логинами тоже не вышло


Login1 := "multilogin1"
Login2 := "multilogin2"
Login3 := "multilogin3"
Login4 := "multilogin4"
Login5 := "multilogin5"
Passw := "multipass"

^!l::LoginFunc()
LoginFunc() {
        ;функция входа в игру
        global wowid1, wowid2, wowid3, wowid4, wowid5
        global Login1,Login2,Login3,Login4,Login5,Passw

        ;SetKeyDelay устанавливает задержку между нажатиями клавишь 100 мсек

        Settimer, LoginWoW1, -1
        Settimer, LoginWoW2, -1
        Settimer, LoginWoW3, -1
        Settimer, LoginWoW4, -1
        Settimer, LoginWoW5, -1
        return

        LoginWoW1:
        SetKeyDelay, 100
        Sleep 50
        ControlSend, , {end}, ahk_id %wowid1%
        Sleep 500
        ControlSend, , {Shift down}{Home}, ahk_id %wowid1%
        Sleep 10
        ControlSend, , {Shift up}, ahk_id %wowid1%
        Sleep 50
        ControlSend, , {Delete}, ahk_id %wowid1%
        Sleep 50
        ControlSend, , %Login1%, ahk_id %wowid1%
        Sleep 500
        ControlSend, , {Tab}, ahk_id %wowid1%
        Sleep 50
        ControlSend, , %Passw%, ahk_id %wowid1%
        Sleep 50
        ControlSend, , {Tab}, ahk_id %wowid1%
        Sleep 50
        ControlSend, , {end}, ahk_id %wowid1%
        SetKeyDelay, 0
        return

        LoginWoW2:
        SetKeyDelay, 100
        Sleep 100
        ControlSend, , {end}, ahk_id %wowid2%
        Sleep 50
        ControlSend, , {Shift down}{Home}, ahk_id %wowid2%
        Sleep 10
        ControlSend, , {Shift up}, ahk_id %wowid2%
        Sleep 10
        ControlSend, , {Delete}, ahk_id %wowid2%
        Sleep 50
        ControlSend, , %Login1%, ahk_id %wowid1%
        Sleep 500
        ControlSend, , {Tab}, ahk_id %wowid1%
        Sleep 50
        ControlSend, , %Passw%, ahk_id %wowid1%
        Sleep 50
        ControlSend, , {Tab}, ahk_id %wowid1%
        Sleep 50
        ControlSend, , {end}, ahk_id %wowid1%
        SetKeyDelay, 0
        return
....
}

Вбивает логины поочередно в каждое окно

7

Re: AHK: Параллельное выполнение команд

Псевдопараллельно. С использованием прерываний. Все как в цитате.
Как вариант еще использовать несколько скриптов ahk, запуская их из одного главного.

8 (изменено: kflirik, 2011-07-04 13:31:52)

Re: AHK: Параллельное выполнение команд

А это идея. Запустить 5 скриптов, в каждом сделать одинаковые горячие клавиши, но отправлять из каждого скрипта команды разным окнам.
А как переменные отдать другим скриптам?
Например у меня сейчас в массив вносятся идентификаторы окон

WinGet, wowid, List, WOW

как мне каждому из 5 скриптов передать свой wowidX, например для

ClonesPush(strKeys) {
        global wowid1

        IfWinNotActive, ahk_id %wowid1%
        ControlSend, , %strKeys%, ahk_id %wowid1%
}
~Left::ClonesPush("{Left down}")
~Left up::ClonesPush("{Left up}")
~Right::ClonesPush("{Right down}")
~Right up::ClonesPush("{Right up}")

? global ведь действителен только для 1 скрипта, Ctrl+V в окне AHK во всяком случае не показывает переменные в другом скрипте.

UPD
Появилась еще 1 проблема - при дублирования нажатия кнопок в неактивные окна, если долго держать кнопку нажатой то в неактивных после отпускание кнопки продолжаются действия. Я думаю это происходит, из-за этого:
- при удержании кнопки начинается повтор нажатий (получается - каждый повтор - самостоятельное нажатие)
- кнопка нажимается в каждое окно по очереди
- между нажатиями в окна проходит какое-то время, хотя SetKeyDelay, -1, -1
- кнопка записывается в буфер и отправляется окнам позже
Это как-то можно решить в 1 скрипте, или все-же делать для каждого окна свой?

9 (изменено: kflirik, 2011-07-04 13:33:41)

Re: AHK: Параллельное выполнение команд

Отдельные скрипты для каждого окна  работают быстрее, но все равно после отпускания клавиши в неактивных окнах она еще нажимается.

Собственно ориентируюсь я на KeyClone, в нем при нажатие и отпускание клавиши работает синхронно для всех окон. С AHK такого вообще возможно добиться? KeyClone мне не подходит т.к. есть проблема с кликами мыши, ну и он платный

10

Re: AHK: Параллельное выполнение команд

Проблему решил отдельным запуском Х'ов с выключенным авто повтором клавиш (да, у меня linux). Также запускаю по отдельному скрипту для каждого окна игры. Визуально задержек между нажатиями во всех окнах не заметно.