1 (изменено: Indomito, 2012-02-26 13:16:59)

Тема: AHK: Как правильно написать скрипт-менеджер других скриптов?

Есть несколько скриптов, как правильно написать скрипт который будет запускать другие при старте конкретного приложения. А после его завершения скрипт будет завершен и будет активирован скрипт управления.
По сути как написать скрипт-менеджер других скриптов, а так же желательно что бы загружал/выгружал или активировал/деактивировал другие скрипты.
Желательно готовый пример.
За основу можно взять например это скрипт

;-----BEGIN--Для SIMS 3 
#IfWinActive ,The Sims™ 3,
SetTitleMatchMode, 2

ESC::
LShift & ESC::
Send {F5}
exit

RShift & Enter::
Tab::
Send {n}
Enter::
MouseClick, right, 20, 910
MouseMove, 620, 475
Sleep, 700
MouseClick, WheelUp, , , 6
exit
;-----END--Для SIMS 3

;-----BEGIN--Для Dragon Age 
#IfWinActive ,Dragon Age: Начало,
SetTitleMatchMode, 2
RShift::
vk2D::
Numpad0::
   Send, {Up Down}{Enter Down}{RButton Down}
   KeyWait, % A_ThisHotkey
   Send, {Up Up}{Enter Up}{RButton Up}
Return
;-----END Для Dragon Age

только строчки #IfWinActive ,..... должны быть в скрипт-менеджере.

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

2

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

В дополнение к скрипт-менеджеру.
Я не уверен насчет строчки #IfWinActive ,..... т.к. при смене окна будет отключение скрипта, что будет приводить к постоянной перегрузке, но это моё мнение.

P.S. OS Win 7 Ult x64 SP1

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

3

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

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

Скрипт-менеджер на примере Total Commander'a, блокнота и браузера Опера:

; AHK_L v. 1.1.5.6 x32 Unicode
; main_script.ahk
#SingleInstance ignore
DetectHiddenWindows , On

array := {"TTOTAL_CMD": "spawn_1", "Notepad": "spawn_2", "OperaWindowClass": "spawn_3"}
Menu, Tray, Icon, Shell32.dll, 44 ; сменить иконку
loop
{
  For key, value in array
  {
  if WinExist("ahk_class "Key)
  {
     if (Opened%key% != 1)
     {
        Run , %value%.ahk
        Opened%key% := 1
     }
  }
  else Opened%key% := 0
  }
    sleep, 1000
}

F12:: pause, toggle
#F12:: ExitApp

Следующие 3 скрипта вызываются при запуске сопоставленного приложения,
и должны быть сохранены под названиями spawn_1.ahk, spawn_2.ahk, spawn_3.ahk соответственно:

;spawn_1.ahk
MsgBox, Total Commander is running.

loop
{
   ; Do something
   sleep 1000
   if !WinExist("ahk_class TTOTAL_CMD")
      break
}

MsgBox, Total Commander was closed.
ExitApp
;spawn_2.ahk
MsgBox, Notepad is running.

loop
{
   ; Do something

   sleep 1000
   if !WinExist("ahk_class Notepad")
      break
}

MsgBox, Notepad was closed.
ExitApp
;spawn_3.ahk
MsgBox, Opera is running.

loop
{
   ; Do something
   sleep 1000
   if !WinExist("ahk_class OperaWindowClass")
      break
}

MsgBox, OPera was closed.

4

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

Irbis пишет:

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

поправил, т.е.  оставил один вопрос.

У меня сомнение вызывает - if !WinExist("ahk_class TTOTAL_CMD"), просто мне не удалось ранее производить проверку пока я не написал так #IfWinActive ,The Sims™ 3,, т.е. по заголовку окна в юникоде.

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

5 (изменено: Irbis, 2012-02-26 13:50:32)

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

Не вижу никаких препятствий использовать if !WinExist("The Sims™ 3"), если вам так удобней.
Кстати, в моем примере вызываемый скрипт работает до тех пор, пока существует окно нужной нам программы, даже если оно свернуто.
Если нужно, чтоб скрипт завершал работу, когда работа идет с другим приложением, нужно поменять
if !WinExist("The Sims™ 3") -> if !WinActive("The Sims™ 3"), в вызываемом скрипте и
if WinExist("ahk_class "Key) -> if WinActive("ahk_class "Key) в скрипт менеджере.

Upd: И конечно же, не if WinExist("ahk_class "Key), а просто if WinExist(Key), если поиск ведется по заголовку окна, а не по его классу.
       Тогда значения Key нужно изменить на заголовки.

6

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

Irbis пишет:

Если нужно, чтоб скрипт завершал работу, когда работа идет с другим приложением, нужно поменять...

да, да это я и забыл спросить. Спасибо

И вопрос.
В скрипт-менеджере есть array := {"TTOTAL_CMD": "spawn_1", "Notepad": "spawn_2", "OperaWindowClass": "spawn_3"}, а как передать параметр в запускаемый скрипт, т.е. что бы не писать два раза название окна.
Это для унификации и для устранение возможных ошибок, т.е. как правильно и корректно описать это.

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

7 (изменено: Irbis, 2012-02-26 17:25:46)

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

Для передачи значения key в качестве параметра, в главном скрипте исправляем:
  Run , %value%.ahk %key%

Тогда в вызываемом скрипте переменная %1% будет содержать 1ый переданный параметр, %2% - 2ой и т.д. (В данном случае параметр один).

tracked_app = %1%
loop
{
   ; Do something
   sleep 1000
   if !WinActive(tracked_app)
      break
}

MsgBox, %tracked_app% is not active.
ExitApp

Upd: Обновленный главный скрипт в посте #9

8

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

Irbis пишет:

Пример с передачей заголовка окна (не класа):

как я понял речь идёт про ahk_class, а не про классы языка.... ну да прочитал выше и понял.
P.S. Мои проблемы с терминологией.

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

9 (изменено: Irbis, 2012-02-26 16:59:40)

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

Внес несколько исправлений в управляющий скрипт:
Во-первых, в array можно указать любые критерии нужного окна, т.е заголовок, класс, PID и прочие параметры, принимаемые WinActive.
Во-вторых, Run заменил на RunWait, так как нет смысла гонять цикл проверки окон, если работает один дочерний скрипт.
В-третьих, в паре ключ:значение в array сменил название запускаемого скрипта на название запускаемой команды, которая может быть любой, поддерживаемой Run

Вот пример, в котором TCommander отслеживается по заголовку, блокнот - по классу окна, а при открытии в Опере серого форума запускается калькулятор:


; AHK_L v. 1.1.5.6 x32 Unicode
#SingleInstance ignore
DetectHiddenWindows , On
SetTitleMatchMode , 2

array :={"Total Commander": "spawn_1.ahk"
       , "ahk_class Notepad": "spawn_2.ahk"
       , "Серый форум ahk_class OperaWindowClass": "calc.exe"}
Menu, Tray, Icon, Shell32.dll, 44 ; сменить иконку
loop
{
  For key, value in array
  {
  if WinActive(Key)
  {
     if (Opened%A_Index% != 1)
     {
        RunWait , %value% "%key%"
        Opened%A_Index% := 1
     }
  }
  else Opened%A_Index% := 0
  }
    sleep, 1000
}

F12:: pause, toggle
#F12:: ExitApp

Логика работы дочернего скрипта из поста #7 не изменится.

10

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

Большое спасибо... буду его разбирать... углублённо

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

11

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

Если можно, то поясните зачем в конце управляющего скрипта написано

F12:: pause, toggle
#F12:: ExitApp

?

И давно хотел спросить...
Имена скриптов написаны без абс. путей, т.е. по умолчанию где они должны расположиться? В любом о писаном пути (в OS) или же только где то конкретно, скажем где установлен  AutoHotKey?

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

12 (изменено: Irbis, 2012-02-29 16:07:14)

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

Я думал, вы немного разбираетесь в вопросе, раз сами пишете скрипты. F12 ставит скрипт на паузу, если нужно временно приостановить его, win+F12 - завершает его работу. Можно через меню в трее, но так быстрей.
Если вам эти дополнительные функции не нужны, эти строки можно удалить.

Вызываемые скрипты кладутся в одну папку с главным, или пишутся полные пути, или в директории, прописанной в системной переменной %PATH%.
Или, если вызываемые скрипты лежат в другом каталоге, можно сменить рабочую директорию командой

SetWorkingDir, DirName

13

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

Нет, то что делают две строчки я то понимаю, но на всякий случай решил переспросить, а то мало ли что....

Спасибо за ответ.

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

14

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

И ещё вопрос.

Компилятор может провести сборку всех ahk-файлов в один или только раздельная компиляция?

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

15 (изменено: Irbis, 2012-02-29 18:00:22)

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

Насколько мне известно, в компиляторе такой возможности не предусмотрено. Можно воспользоваться каким-либо инталлятором, который собирет файлы в один установочный,
но при установке они все равно распакуются. Такими же возможностями - созданием self-extraсting архивов - обладают и архиваторы, например winrar и winzip.
Если так необходимо, чтоб был именно один файл, почему бы вызываемые скрипты не оформить в виде процедур? У вас они работает по очереди, проблем возникнуть не должно.

Пример: (куда уж без него)

; AHK_L v. 1.1.5.6 x32 Unicode
#SingleInstance ignore
DetectHiddenWindows , On
SetTitleMatchMode , 2
 
array :={"Total Commander": "func1"
       , "ahk_class Notepad": "func2"
       , "ahk_class OperaWindowClass": "func3"}
Menu, Tray, Icon, Shell32.dll, 44
loop
{
  For key, value in array
  {
  if WinActive(Key)
  {
     if (Opened%A_Index% != 1)
     {
        %value%(key)
        Opened%A_Index% := 1
     }
  }
  else Opened%A_Index% := 0
  }
    sleep, 1000
}
 
F12:: pause, toggle
#F12:: ExitApp

;1ый скрипт -------------------------- 
func1(tracked_app)
{
loop
{
   ; Do something
   sleep 1000
   if !WinActive(tracked_app)
      break
}
MsgBox, %tracked_app% is not active.
}

;2ой скрипт -------------------------- 
func2(tracked_app)
{
loop
{
   ; Do something
   sleep 1000
   if !WinActive(tracked_app)
      break
}
MsgBox, %tracked_app% is not active.
}

;3ий скрипт -------------------------- 
func3(tracked_app)
{
loop
{
   ; Do something
   sleep 1000
   if !WinActive(tracked_app)
      break
}
MsgBox, %tracked_app% is not active.
}

16

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

Да, в одном файле проще... думаю с видимостью переменных проблем не будет, но я сам разберусь - RTFM

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

17 (изменено: Indomito, 2012-02-29 18:46:49)

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

Прошу прощения за тормоза, но возник вопрос, т.е. сразу два.

Вопрос №1

Коммнентарий Do something (Сделать это/Сделайте что-то) подрузамевает:
На примере одной из функции.

;1ый скрипт -------------------------- 
func1(tracked_app)
{
loop
{
   ; Do something

ESC::                   ;<------------------
LShift & ESC::       ;<------------------
Send {F5}            ; <------------------

   sleep 1000
   if !WinActive(tracked_app)
      break
}
MsgBox, %tracked_app% is not active.
}

верно вставил или нет?
Вопрос возник из за строчки sleep 1000, т.е. она должна идти первой или же последней или же вообще не нужна?

Вопрос №2

Если в функциях будут описаны действия на одну и туже клавишу, то коллизий не возникнет?
Я понимаю что не должно, вроде бы, но я не уверен.

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

18 (изменено: Irbis, 2012-03-01 01:39:07)

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

По 1ому вопросу:
В моем примере sleep 1000 просто задает паузу, чтоб скрипт меньше загружал процессор, так как там крутится практически пустой цикл.
Так, как в вашем примере, вставлять нельзя - при нажатии на хоткей произойдет безусловный переход, причем сразу в середину цикла.

И собственно, по 2 вопросу, который связан с первым - чтобы на одну и ту же клавишу задать разные действия, надо или самому организовать переключение, или использовать IfWinActive.
А написать 2 подпрограммы с одинаковыми хоткеями не получится, получите ошибку Duplicate hotkey.
Смотрите описание Hotkey. Если использовать  IfWinActive для создания одинаковых хоткеев,
тогда опять придем практически к примеру из вашего первого поста, с которого все и началось

Hotkey, IfWinActive ,The Sims™ 3
Hotkey, LShift & ESC, The_Sims

Hotkey, IfWinActive ,Dragon Age : Начало
Hotkey, LShift & ESC, Dragon_Age

The_Sims:
  Send {F5}
return

Dragon_Age:
  Send, {Up Down}{Enter Down}{RButton Down}
  KeyWait, % A_ThisHotkey
  Send, {Up Up}{Enter Up}{RButton Up}
return

Вместо ; Do something в процедурах func1, func2 и т.д. пишется код, который должен атоматически выполняться при активации нужного приложения:

func1(tracked_app)
{
   ;------------------------------------------------------------------
   ; здесь код, запускаемый однократно при активации приложения
   ;------------------------------------------------------------------
   loop
   {
      ;------------------------------------------------------------------
      ; здесь код, выполняемый в цикле при активном приложении
      ;------------------------------------------------------------------

      sleep 1000 ; <-- задержка повтора кода в цикле
      if !WinActive(tracked_app)
      break
   }
   ;------------------------------------------------------------------
   ; здесь код, выполняемый однократно при потере фокуса/закрытии
   ;------------------------------------------------------------------
}

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

19

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

Поздно. Я уже прочитал
Метка не локальная переменная, верно, но использование меток для переходов (читай - Goto) очень дурной стиль, растущий корнями из далекого-далекого бейсика,
и без очень уважительной причины должен караться битием по рукам. Имхо.

20

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

И так видимо для простоты + унификации + понижения путаницы и коллизий надо:
- отказаться от компиляции;
- использовать для каждой программы свой ahk-файл.

Верно?

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

21

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

OFF: Irbis, вы либо меня не поняли, либо отклоняетесь от темы.

22 (изменено: Irbis, 2012-03-01 00:27:32)

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

creature.ws, видимо.

Indomito, компиляция либо отказ от нее никак никак не влияет на простоту кода и прочие параметры.
Если  есть возможность, лучше использовать один файл, при необходимости подключая большие  части директивой #Include <Filename>,
либо использовать библиотеки.

23

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

Irbis и в дополнение про ahk-файла в виде подпрограммы/функции
Что надо поправить в коде, что бы было различие между выходом из приложения и его минимизацией/потерей фокуса.
Т.е. что бы оно оставалось в трее, но не работало или это немного наворочено будет, т.к. его повторная активация часть кода ahk-менеджера?

tracked_app = %1%

ESC::
LShift & ESC::
Send {F5}

loop
{
   ; Do something
   sleep 1000
   if !WinActive(tracked_app)
      break
}
 
MsgBox, %tracked_app% is not active.
ExitApp
"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

24 (изменено: Indomito, 2012-03-01 00:50:05)

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

Indomito,

компиляция либо отказ от нее никак никак не влияет на простоту кода и прочие параметры.
Если  есть возможность, лучше использовать один файл, при необходимости подключая большие  части директивой #Include <Filename>,
либо использовать библиотеки.

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

add

А если написать вначале каждой функции
Hotkey, IfWinActive ,The Sims™ 3
Разве это не верно?

Я про такую запись

;1ый скрипт -------------------------- 
func1(tracked_app)
{
Hotkey, IfWinActive , %tracked_app%
ESC::                   
LShift & ESC::       
Send {F5}            
loop
{
   ; Do something
   sleep 1000
   if !WinActive(tracked_app)
      break
}
MsgBox, %tracked_app% is not active.
}
"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

25 (изменено: Irbis, 2012-03-01 01:12:45)

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

Indomito пишет:

Irbis и в дополнение про ahk-файла в виде подпрограммы/функции
Что надо поправить в коде, что бы было различие между выходом из приложения и его минимизацией/потерей фокуса.
Т.е. что бы оно оставалось в трее, но не работало или это немного наворочено будет, т.к. его повторная активация часть кода ahk-менеджера?

#SingleInstance ignore
tracked_app = %1%

; код, запускаемый однократно при активации приложения

loop
{
   ; код, выполняемый в цикле при активном приложении

   sleep 10 ; <-- задержка повтора кода в цикле
   if !WinExist(tracked_app)
      break
   if !Winactive(tracked_app)
   {
        ; код, выполняемый при потере фокуса
   }
   WinWaitActive, %tracked_app%
}
; код, выполняемый однократно при закрытии

ExitApp
ESC::
LShift & ESC::
Send {F5}
return

26

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

По поводу

Hotkey, IfWinActive , %tracked_app%

Вы задаете условие, но не сам хоткей, тогда уж надо так:

; начало скрипта
Hotkey, IfWinActive , %tracked_app%
Hotkey, LShift & ESC, The_Sims

...
...

; конец скрипта, после ExitApp

The_Sims:
   Send {F5} 
return

27 (изменено: Indomito, 2012-03-01 01:32:49)

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

---удалил, т.к.  все конструкции сводятся к моему первому посту...
Упростить код, т.е. исходник не удаётся. Да, жаль конечно, но отслеживать дубль-клавиши не хочется, хотя можно их вынести в include, но это я сам себя ещё больше запутаю

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download

28 (изменено: Irbis, 2012-03-01 01:34:30)

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

Непонятно, к чему Hotkey, LShift & ESC, The_Sims три раза подряд? Чтоб скрипт совсем-совсем понял?
И если есть метка The_Sims:, то LShift & ESC:: перед Send {F5} писать уже не нужно

29

Re: AHK: Как правильно написать скрипт-менеджер других скриптов?

я не дописал тогда, а когда дописал, то получилась ерунда

"На каждое действие есть равная ему противодействующая критика." Постулат Харриссона
OS Windows 7 x64
AutoHotkey v1.1.32.00 - November 24, 2019
Click to Download