1 (изменено: Malcev, 2015-08-05 23:05:34)

Тема: AHK: Асинхронный запуск скриптов

Имеется 5 скриптов, которые в цикле в разное время могут выдать msgbox.
Как сделать так, чтобы 2 msgbox не появились одновременно? (msgbox - только как пример, вместо него может быть, что угодно, например отправка писем)?
Пока родилась такая идея:

loop, 5
{
   fileappend,
   (
      loop
      {
         Random, rand, 3000, 7000
         sleep, `%rand`%
         fileappend, 
         (
            MsgBox,,,,1
         `), test`%A_Index`%`%A_ScriptName`%, UTF-8
      }
   ), script%A_Index%.ahk, UTF-8
   run, script%A_Index%.ahk
}

fileappend,
(
   loop
   {
      loop, test*.ahk,
      {
         RunWait, `%A_LoopFileName`%
         FileDelete, `%A_LoopFileName`%
      }
   }
), check.ahk, UTF-8
run, check.ahk

Может есть способы получше?

2

Re: AHK: Асинхронный запуск скриптов

Непонятно, какая цель всего этого. В чём задача-то?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3

Re: AHK: Асинхронный запуск скриптов

Информировать через скайп клиентов о готовности их продукта.
Так как через скайп можно передать через коммандную строку только одно сообщение за раз, то нужно сделать подобие очереди.

4

Re: AHK: Асинхронный запуск скриптов

А почему нельзя в одном скрипте циклом через паузу?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

5 (изменено: Malcev, 2015-07-09 17:46:53)

Re: AHK: Асинхронный запуск скриптов

Потому что скрипты работают одновременно.
Они разной направленности.
Какой-то парсит один сайт, какой-то другой.
Я проверял - асинхронный метод winhttprequest в одном скрипте работает медленнее, чем запустить просто несколько скриптов с winhttprequest.

6

Re: AHK: Асинхронный запуск скриптов

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

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

7 (изменено: Irbis, 2015-07-09 18:15:35)

Re: AHK: Асинхронный запуск скриптов

Запустить скрипт-обработчик. А ему передавать можно хоть через буфер,  хоть через Messages, да даже temp-файл сгодится. Были на форуме темы по взаимодействию скриптов.

Upd: Надо взять за правило обновлять тему перед отправкой поста.)

8

Re: AHK: Асинхронный запуск скриптов

Запустить скрипт-обработчик. А ему передавать можно хоть через буфер,  хоть через Messages, да даже temp-файл сгодится.

Через Temp-file я указал в примере.
А можно пример того, как скрипт-обработчик будет ставить их в очередь через Messages?
Допустим 3 исходных скрипта одновременно пошлют ему сообщение, а он приняв их должен будет каждое сообщение по очереди вывести мессаджбоксом и подержать 3 секунды.

9

Re: AHK: Асинхронный запуск скриптов

Я только вечером смогу.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

10 (изменено: Alectric, 2015-07-09 20:04:42)

Re: AHK: Асинхронный запуск скриптов

Решил попробовать.
Главный скрипт:

OnMessage(0x1002,"Function")  ; принимаем сообщение от скриптов.

Loop  ; наверное можно сделать и без цикла, но мне так привычней и надежней.
{
  sleep,1000
  tooltip,% line    ; Осталось парсить эту строку и выдавать разрешение по очереди каждому скрипту.
  loop,parse,line
  {
;    tooltip,% a_loopfield "`n" a_tickcount
    dnes(a_loopfield,1)
    line:=RegExReplace(line, a_loopfield , "")
    gosub,Wait_done  ; ждать завершения.
  }
}


Wait_done:  ; можно принять сообщение о завершении работы для выдачи следующего разрешения.
loop,1000000 ;  ограниченный цикл, если что-то пойдет не так.
{
  sleep,1000
  if done
    break
}
done=
return


Function(wParam,lParam,Msg,hwnd)
{
  global
;  msgbox,%a_tickcount%`n"%wParam%"`n"%lParam%"`n"%Msg%"`n"%hwnd%"

  if wParam=0xff
    done:=lParam
  else
    line.=wParam
}

dnes(index,permission) ; index - номер скрипта, permission - разрешение на продолжение действий.
{
  DetectHiddenWindows,On
  WinGet,Array_id,list,ahk_class AutoHotkey
  Loop,%Array_id%
    sendMessage,0x1003,%Index%,%permission%,,% "ahk_id" Array_id%A_Index%
}

Остальные скрипты:

OnMessage(0x1003,"Function")  ; принимаем сообщение от главного скрипта.

Function(wParam,lParam,Msg,hwnd)
{
  global
;  msgbox,%a_tickcount%`n"%wParam%"`n"%lParam%"`n"%Msg%"`n"%hwnd%"
  if (wParam=1 and lParam=1)
  {
    msgbox,% wParam
    dnes(0xff,1)    ; говорим о завершении работы.
  }
  if (wParam=2 and lParam=1)
  {
    msgbox,% wParam
    dnes(0xff,1)    ; говорим о завершении работы.
  }
  if (wParam=3 and lParam=1)
  {
    msgbox,% wParam
    dnes(0xff,1)    ; говорим о завершении работы.
  }
  if (wParam=4 and lParam=1)
  {
    msgbox,% wParam
    dnes(0xff,1)    ; говорим о завершении работы.
  }
  if (wParam=5 and lParam=1)
  {
    msgbox,% wParam
    dnes(0xff,1)    ; говорим о завершении работы.
  }
}

dnes(Index,ready) ; index - номер скрипта, ready - ready.
{
  DetectHiddenWindows,On
  WinGet,Array_id,list,ahk_class AutoHotkey
  Loop,%Array_id%
    sendMessage,0x1002,%Index%,%ready%,,% "ahk_id" Array_id%A_Index%
}


!f1::
dnes(1,1) ; говорим главному что готовы встать в очередь.
return

!f2::
dnes(2,1)
return

!f3::
dnes(3,1)
return

!f4::
dnes(4,1)
return

!f5::
dnes(5,1)
return



Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

11 (изменено: Alectric, 2015-07-09 19:59:37)

Re: AHK: Асинхронный запуск скриптов

Чуть подправил.
5 штук в одном скрипте - только для теста.

Исправил еще ошибку.

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

12

Re: AHK: Асинхронный запуск скриптов

А если общее число скриптов неизвестно и и нету главного.
Есть n-ое количество скриптов и скрипт-обработчик.
Хотелось бы получить аналогичные действия, что и в моем примере с 1-ого поста, только без использования временных файлов.

13 (изменено: Alectric, 2015-07-09 20:15:39)

Re: AHK: Асинхронный запуск скриптов

Скрипт-обработчик и есть в моем понимании главный скрипт.
Думаю что в любом случае скриптам придется присвоить каждому свой номер, а главный скрипт уже работает с номерами, максимум 0xFE скриптов могут встать в очередь, но можно и больше ведь lParam практически и не используется (единица везде).

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

14 (изменено: Alectric, 2015-07-09 20:14:11)

Re: AHK: Асинхронный запуск скриптов

Т.е. в каждом скрипте должно быть следующее:

ScriptNumber=1

OnMessage(0x1003,"Function")  ; принимаем сообщение от главного скрипта.

Function(wParam,lParam,Msg,hwnd)
{
  global
;  msgbox,%a_tickcount%`n"%wParam%"`n"%lParam%"`n"%Msg%"`n"%hwnd%"
  if (wParam=ScriptNumber and lParam=1)
  {
    msgbox,% wParam
    dnes(0xff,1)    ; говорим о завершении работы.
  }
}

dnes(Index,ready)
{
  DetectHiddenWindows,On
  WinGet,Array_id,list,ahk_class AutoHotkey
  Loop,%Array_id%
    sendMessage,0x1002,%Index%,%ready%,,% "ahk_id" Array_id%A_Index%
}

!f1::
dnes(ScriptNumber,1) ; говорим главному что готовы встать в очередь.
return

Где"ScriptNumber" и есть индивидуальный номер скрипта... хотя можно завязать и на имя файла скрипта... как-нибудь... или сделать автоматическое распределение номеров...

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

15

Re: AHK: Асинхронный запуск скриптов

Как-то неправильно он работает.
Создаем 5 скриптов, меняя только ScriptNumber и одновременно запускаем их.
Получаем, не равномерную очередь, а повторяющуюся из одних и тех же скриптов.

OnMessage(0x1003,"Function")  ; принимаем сообщение от главного скрипта.
ScriptNumber=1
loop
{
   dnes(ScriptNumber,1) ; говорим главному что готовы встать в очередь.
   sleep, 1000
}

Function(wParam,lParam,Msg,hwnd)
{
  global
;  msgbox,%a_tickcount%`n"%wParam%"`n"%lParam%"`n"%Msg%"`n"%hwnd%"
  if (wParam=ScriptNumber and lParam=1)
  {
    MsgBox,,,%wParam%,1
    dnes(0xff,1)    ; говорим о завершении работы.
  }
}

dnes(Index,ready)
{
  DetectHiddenWindows,On
  WinGet,Array_id,list,ahk_class AutoHotkey
  Loop,%Array_id%
    sendMessage,0x1002,%Index%,%ready%,,% "ahk_id" Array_id%A_Index%
}

16 (изменено: Alectric, 2015-07-09 20:39:54)

Re: AHK: Асинхронный запуск скриптов

Если все скрипты дают запрос с одинаковым интервалом, то вроде все правильно.

Вот вариант с авто-распределением номеров:
главный:

OnMessage(0x1002,"Function")  ; принимаем сообщение от скриптов.

Loop  ; наверное можно сделать и без цикла, но мне так привычней и надежней.
{
  sleep,1000
  tooltip,% line    ; Осталось парсить эту строку и выдавать разрешение по очереди каждому скрипту.
  loop,parse,line,`,
  {
    if !a_loopfield
      continue
;    msgbox,% a_loopfield "`n" a_tickcount
    dnes(a_loopfield,1)
    line:=RegExReplace(line, a_loopfield "`,", "")
    gosub,Wait_done  ; ждать завершения.
  }
}


Wait_done:  ; можно принять сообзение о завершении работы для выдачи следующего разрешения.
loop,1000000
{
  tooltip,Wait
  sleep,100
  if done
    break
}
done=
return


Function(wParam,lParam,Msg,hwnd)
{
  global
  msgbox,%a_tickcount%`n"%wParam%"`n"%lParam%"`n"%Msg%"`n"%hwnd%"

  if (wParam=0xff and lParam=1)
    done=1
  else if (wParam=0xff and lParam=0xff) ; авто получение номера.
  {
    num++
    dnes(num,0xff) ; отправка номера скрипту.
  }
  else
    line.=wParam "`,"
}

dnes(index,permission) ; index - номер скрипта, permission - разрешение на продолжение действий.
{
  DetectHiddenWindows,On
  WinGet,Array_id,list,ahk_class AutoHotkey
  Loop,%Array_id%
    sendMessage,0x1003,%Index%,%permission%,,% "ahk_id" Array_id%A_Index%
}

Остальные:

OnMessage(0x1003,"Function")  ; принимаем сообщение от главного скрипта.

dnes(0xff,0xff) ; запрос на получение номера

Function(wParam,lParam,Msg,hwnd)
{
  global
;  msgbox,%a_tickcount%`n"%wParam%"`n"%lParam%"`n"%Msg%"`n"%hwnd%"
  if lParam=0xff
    ScriptNumber:=wParam
  if (wParam=ScriptNumber and lParam=1)
  {
    msgbox,% wParam
    dnes(0xff,1)    ; говорим о завершении работы.

                                               dnes(ScriptNumber,1) ; следующий запрос.

  }
}

dnes(Index,ready)
{
  DetectHiddenWindows,On
  WinGet,Array_id,list,ahk_class AutoHotkey
  Loop,%Array_id%
    sendMessage,0x1002,%Index%,%ready%,,% "ahk_id" Array_id%A_Index%
}

!f1::
dnes(ScriptNumber,1) ; говорим главному что готовы встать в очередь.
return
Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

17 (изменено: Alectric, 2015-07-09 20:37:38)

Re: AHK: Асинхронный запуск скриптов

loop
{
   dnes(ScriptNumber,1) ; говорим главному что готовы встать в очередь.
   sleep, 1000
}

И тут у тебя запросы на очередь отправляются беспрерывно каждую секунду.
А нужно отправить запрос 1 раз и ждать разрешения, затем отправлять еще запрос.

Function(wParam,lParam,Msg,hwnd)
{
  global
;  msgbox,%a_tickcount%`n"%wParam%"`n"%lParam%"`n"%Msg%"`n"%hwnd%"
  if lParam=0xff
    ScriptNumber:=wParam
  if (wParam=ScriptNumber and lParam=1)
  {
    msgbox,% wParam
    dnes(0xff,1)    ; говорим о завершении работы.
                                                     dnes(ScriptNumber,1) ; отправляем следующий запрос.
  }
}
Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

18 (изменено: serzh82saratov, 2015-07-09 20:48:54)

Re: AHK: Асинхронный запуск скриптов

Если темп файл не устраивает, то я не надеялся бы на очередь сообщений. Думаю если передавать в сообщении текст (WM_COPYDATA), и его добавлять в переменную, а далее её разбирать, удаляя обработанное, то может и получится обработать без потерь довольно большую очередь инструкций.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

19

Re: AHK: Асинхронный запуск скриптов

я не надеялся бы на очередь сообщений.

Почему?
И с Temp file это как?
У меня сейчас создаются скрипты с названием даты времени создания, которые запускаются и удаляются.
Это правильно?

loop, 5
{
   fileappend,
   (
      loop
      {
         Random, rand, 100, 500
         sleep, `%rand`%
         fileappend, 
         (
            MsgBox,,,,1
         `), test`%A_TickCount`%`%A_ScriptName`%, UTF-8
      }
   ), script%A_Index%.ahk, UTF-8
   run, script%A_Index%.ahk
}

fileappend,
(
   loop
   {
      loop, test*.ahk,
      {
         RunWait, `%A_LoopFileName`%
         FileDelete, `%A_LoopFileName`%
      }
   }
), check.ahk, UTF-8
run, check.ahk

20 (изменено: serzh82saratov, 2015-07-09 21:31:30)

Re: AHK: Асинхронный запуск скриптов

Почему?

Там какое то ограничение на память, или кол-во сообщений, но не уверен.

У меня сейчас создаются скрипты с названием даты времени создания, которые запускаются и удаляются.
Это правильно?

Может и пойдёт, сейчас если честно копатся не хочется. Но наверное я бы в один файл дописывал, +посылал бы сообщение об этом. Если в одну милисекунду попасть, то не понятно какой из файлов запишется. А если в этот момент другой пишет в тот же файл, то это можно проверить, и подождать.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

21

Re: AHK: Асинхронный запуск скриптов

serzh82saratov пишет:

не надеялся бы на очередь сообщений.

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

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

22 (изменено: serzh82saratov, 2015-07-09 21:46:30)

Re: AHK: Асинхронный запуск скриптов

Ну да, только речь до сих пор про сообщения. Сможет ли Critical (или какой другой метод) в OnMessage, прервать текущий поток, и хотя бы просто записать текст в переменную, лично для меня больше вопрос практики, а не теории, ибо не подкован.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

23 (изменено: Alectric, 2015-07-09 21:55:07)

Re: AHK: Асинхронный запуск скриптов

Я тоже об этом, уже проверил - не помогает. В качестве альтернативы темп-файлу могу предложить временные данные в реестре, уже делал как-то раз.
Хотя, вроде, реестр это тоже файл где-то в c:\windows.

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

24

Re: AHK: Асинхронный запуск скриптов

Если в одну милисекунду попасть, то не понятно какой из файлов запишется

А кроме милисекунд я еще добавляю имя файла, так что запишутся все.

А если в этот момент другой пишет в тот же файл, то это можно проверить, и подождать

А если они одновременно обратятся к файлу, то что произойдет?

25

Re: AHK: Асинхронный запуск скриптов

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

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

26

Re: AHK: Асинхронный запуск скриптов

Только недавно столкнулся с интерфейсом СОМ. Так он вроде только через файл и работает. Так что пока наверное рано разевать рот, на хакерские штучки, да ещё и через скриптовый язык.
P.S. Так я и не нашёл примеров записи\чтения в оперативку, конечно после обще известного и доступного пространства в нём. Попытки создания виртуального HID, тоже не увенчались.

А если они одновременно обратятся к файлу, то что произойдет?

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

В реестре каждый скрипт пишет

А реестр, это не файл?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

27

Re: AHK: Асинхронный запуск скриптов

Файл, но в плане одновременной записи заморачиваться уже не нужно будет.

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

28

Re: AHK: Асинхронный запуск скриптов

Возможно и так, а есть практика? В чём по вашему может заключатся отличие, в очереди записи в файл?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

29 (изменено: Alectric, 2015-07-09 22:25:43)

Re: AHK: Асинхронный запуск скриптов

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

OFF: Надо поспать.

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

30

Re: AHK: Асинхронный запуск скриптов

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

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

31

Re: AHK: Асинхронный запуск скриптов

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

Как проснешься, выложишь пример?

32

Re: AHK: Асинхронный запуск скриптов

Malcev пишет:

Имеется 5 скриптов, которые в цикле в разное время могут выдать msgbox.
Как сделать так, чтобы 2 msgbox не появились одновременно? (msgbox - только как пример, вместо него может быть, что угодно, например отправка писем)?

Вроде всё просто. Пишем дополнительный скрипт с GUI-окном (можно невидимым), содержащим э. у. "Text".
Когда скрипт №1 хочет отправить письмо, он проверяет содержимое "Text". Если пусто, он вписывает туда цифру 1, ждёт полсекунды и снова проверяет. Если там стоит 1 (значит конфликтов нет),  то он отправляет письмо, после чего стирает свою единичку. Если "Text" не пустой или в нём стоит чужая цифра, то подождать секунду и повторить попытку.

То же самое для остальных 4 скриптов, только вместо 1 будет 2, 3, 4 и 5.

33

Re: AHK: Асинхронный запуск скриптов

Ну а если 2 скрипта одновременно обратятся к этому контролу и оба получат пустое место?
Точнее друг-за-другом. Первый не успеет вписать единичку, а второй уже обратится.
И очередь там не создать в порядке отправки сообщений.

34

Re: AHK: Асинхронный запуск скриптов

Если оба получат пустое место, то оба впишут свою цифру один из них увидит, что цифра не его. И подождёт, пока другой (другие) доделает свою работу.

А про создание очереди в задании ничего не сказано. Я только обеспечил асинхронную работу скриптов.

35

Re: AHK: Асинхронный запуск скриптов

Если оба получат пустое место, то оба впишут свою цифру один из них увидит, что цифра не его

Так получается, что оба и увидят, что цифра не их.

36

Re: AHK: Асинхронный запуск скриптов

Первый поставил цифру 1.
Второй поставил цифру 2.

Первый проверил - цифра не его, надо подождать.
Второй проверил - цифра его. Отправил. Стёр свою цифру.

Первый подождал и повторил попытку заново. В этот раз ему никто не помешал, и он отправил.

37

Re: AHK: Асинхронный запуск скриптов

Да, теперь понял.
Тогда, наверное, удобней использовать реестр для вставки цифр?

38

Re: AHK: Асинхронный запуск скриптов

Реестр хранится на жёстком диске, а протирать в нём дырку частыми мелкими перезаписями - не культурно.

Создать невидимое окно правильнее - информация будет висеть в оперативной памяти. Это, конечно, костыль, зато будет надёжно работать.

39

Re: AHK: Асинхронный запуск скриптов

А как порядок очереди в этот вариант добавить есть идеи?

40 (изменено: teadrinker, 2015-07-10 09:20:11)

Re: AHK: Асинхронный запуск скриптов

Мой вариант. Предположим, есть 5 скриптов, которые посылают свой текст главному. Посылать они могут в любое время, могут "одновременно". Пусть обработка текстов у главного скрипта занимает какое-то время, а в это время могут приходить новые сообщения. Задача создать из этих сообщений очередь, чтобы они обрабатывались в порядке прибытия, и чтобы никакое сообщение не было потеряно. Если воспользоваться сообщением WM_COPYDATA, то возникает проблема отсутствия его буферизации, т. к. его номер ниже 0x312. Чтобы обойти это, можно воспользоваться своим сообщением, получаемым с помощью RegisterWindowMessage(). Диапазон таких сообщений — 0xC000 - 0xFFFF, т. е. больше 0x312, и такие сообщения будут буферизироваться. В его wp и lp параметрах можно посылать PID отправляющего скрипта, длину и пойнтер переменной с текстом, а затем считывать текст из адресного пространства посылающего скрипта.

Следующий скрипт создаёт пять дочерних скриптов, которые сразу же посылают свои сообщения родительскому скрипту. Обработка каждого занимает две секунды (реализовано с помощью Sleep), сообщения же, которые приходят во время обработки предыдущих, буферизируются, и обрабатываются в свою очередь.

OnMessage(DllCall("RegisterWindowMessage", Str, "WM_INFO"), "WM_INFO_RECEIVER")
ChildrenPIDs := []
Exit := Func("Exit").Bind(ChildrenPIDs)
OnExit(Exit)

Loop 5
   ScriptCreator(ChildrenPIDs, A_Index)
Return

Esc:: ExitApp

ScriptCreator(ChildrenPIDs, N)
{
   Script =
   (
      #Persistent
      ParentHWND := %A_ScriptHwnd%
      MyPID := DllCall("GetCurrentProcessId")
      MyNumber := %N%
      WM_INFO := DllCall("RegisterWindowMessage", Str, "WM_INFO")
      
      Text := "Это текст от скипта №" MyNumber
      wp := (StrLen(Text) * (A_IsUnicode ? 2 : 1)) << 16|MyPID
      lp := &Text
      DllCall("PostMessage", Ptr, ParentHWND, UInt, WM_INFO, Ptr, wp, Ptr, lp)
   )
   ChildPID := ExecScript(Script)
   ChildrenPIDs.Push(ChildPID)
}

WM_INFO_RECEIVER(wp, lp)
{
   static PROCESS_VM_OPERATION := 0x8, PROCESS_VM_READ := 0x10
   Critical
   PID := wp & 0xFFFF
   Pointer := lp
   BuffSize := wp >> 16
   VarSetCapacity(LocalBuff, BuffSize, 0)
   
   if !hProc := DllCall("OpenProcess", UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ, Int, 0, UInt, PID, Ptr)
      Return
   
   res := DllCall("ReadProcessMemory", Ptr, hProc, Ptr, Pointer, Ptr, &LocalBuff, Ptr, BuffSize, Ptr, 0)
   DllCall("CloseHandle", Ptr, hProc)
   if !res
      Return
   
   CoordMode, ToolTip
   ToolTip % StrGet(&LocalBuff), A_ScreenWidth//2 - 100, A_ScreenHeight//2
   Sleep, 1000
   ToolTip
   Sleep, 1000
}
   
ExecScript(Script)
{
   shell := ComObjCreate("WScript.Shell")
   exec := shell.Exec(A_AhkPath " *")
   exec.StdIn.Write(script)
   exec.StdIn.Close()
   return exec.ProcessID
}
   
Exit(PidArray)
{
   DetectHiddenWindows, On
   for k, PID in PidArray
      WinClose, ahk_pid %PID%
}

Нужно иметь в виду, что скрипт во время демонстрации MsgBox не может мониторить сообщения, поэтому они в примере показываются в ToolTip'е.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

41 (изменено: Malcev, 2015-07-10 05:45:53)

Re: AHK: Асинхронный запуск скриптов

Вот я переделал его. Правильно?
Следящий скрипт - check.ahk:

OnMessage(DllCall("RegisterWindowMessage", Str, "WM_INFO"), "WM_INFO_RECEIVER")

WM_INFO_RECEIVER(wp, lp)
{
   static PROCESS_VM_OPERATION := 0x8, PROCESS_VM_READ := 0x10
   Critical
   PID := wp & 0xFFFF
   Pointer := lp
   BuffSize := wp >> 16
   hProc := DllCall("OpenProcess", UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ, Int, 0, UInt, PID, Ptr)
   VarSetCapacity(LocalBuff, BuffSize, 0)
   DllCall("ReadProcessMemory", Ptr, hProc, Ptr, Pointer, Ptr, &LocalBuff, Ptr, BuffSize, Ptr, 0)
   DllCall("CloseHandle", Ptr, hProc)
   ToolTip % StrGet(&LocalBuff), A_ScreenWidth//2 - 100, A_ScreenHeight//2
   Sleep, 1000
   ToolTip
   Sleep, 1000
}

Child-Скрипт 1ый из 5:

SetTitleMatchMode, 2
DetectHiddenWindows on
WinGet, ParentHWND, id, check
MyPID := DllCall("GetCurrentProcessId")
MyNumber := 1
WM_INFO := DllCall("RegisterWindowMessage", Str, "WM_INFO")
loop
{
   Random, rand, 1, 10
   Text := "Это текст от скипта №" MyNumber "`n" rand
   wp := (StrLen(Text) * (A_IsUnicode ? 2 : 1)) << 16|MyPID
   lp := &Text
   DllCall("PostMessage", Ptr, ParentHWND, UInt, WM_INFO, Ptr, wp, Ptr, lp)
   sleep, 1000
}

Минусы увидел следующие - если во время работы какой-либо child-скрипт закрыть - начинаются тормоза и новые запущенные child-скрипты не подхватываются.

42 (изменено: teadrinker, 2015-07-10 09:20:26)

Re: AHK: Асинхронный запуск скриптов

Следящий скрипт модифицировать так:

OnMessage(DllCall("RegisterWindowMessage", Str, "WM_INFO"), "WM_INFO_RECEIVER")

WM_INFO_RECEIVER(wp, lp)
{
   static PROCESS_VM_OPERATION := 0x8, PROCESS_VM_READ := 0x10
   Critical
   PID := wp & 0xFFFF
   Pointer := lp
   BuffSize := wp >> 16
   VarSetCapacity(LocalBuff, BuffSize, 0)
   
   if !hProc := DllCall("OpenProcess", UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ, Int, 0, UInt, PID, Ptr)
      Return
   
   res := DllCall("ReadProcessMemory", Ptr, hProc, Ptr, Pointer, Ptr, &LocalBuff, Ptr, BuffSize, Ptr, 0)
   DllCall("CloseHandle", Ptr, hProc)
   if !res
      Return
   
   CoordMode, ToolTip
   ToolTip % StrGet(&LocalBuff), A_ScreenWidth//2 - 100, A_ScreenHeight//2
   Sleep, 1000
   ToolTip
   Sleep, 1000
}

Посылающий:

SetTitleMatchMode, 2
DetectHiddenWindows on
WinGet, ParentHWND, id, check.ahk ahk_class AutoHotkey
MyPID := DllCall("GetCurrentProcessId")
MyNumber := 1
WM_INFO := DllCall("RegisterWindowMessage", Str, "WM_INFO")
Text := "Это текст от скипта №" MyNumber
wp := (StrLen(Text) * (A_IsUnicode ? 2 : 1)) << 16|MyPID
lp := &Text
loop
{
   DllCall("PostMessage", Ptr, ParentHWND, UInt, WM_INFO, Ptr, wp, Ptr, lp)
   sleep, 1000
}

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

   Sleep, 1000
   ToolTip
   Sleep, 1000

из принимающего скрипта.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

43

Re: AHK: Асинхронный запуск скриптов

Каждый раз поднимая эту тему, возникают новые идеи. В сравнении с предыдущими версиями, чтение из памяти выглядит самой разумной.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

44

Re: AHK: Асинхронный запуск скриптов

Я правильно думаю, что для работы с памятью нужно будет передавать скриптам адреса переменных? Наверное теми же sendmessage.

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

45

Re: AHK: Асинхронный запуск скриптов

Да.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

46

Re: AHK: Асинхронный запуск скриптов

А если мне надо каждый раз новый текст отправлять, то разве неправильно будет исправить посылающий вот так?

SetTitleMatchMode, 2
DetectHiddenWindows on
WinGet, ParentHWND, id, check.ahk ahk_class AutoHotkey
MyPID := DllCall("GetCurrentProcessId")
MyNumber := 1
WM_INFO := DllCall("RegisterWindowMessage", Str, "WM_INFO")
loop
{
   Text := "Это текст от скипта №" MyNumber
   wp := (StrLen(Text) * (A_IsUnicode ? 2 : 1)) << 16|MyPID
   lp := &Text
   DllCall("PostMessage", Ptr, ParentHWND, UInt, WM_INFO, Ptr, wp, Ptr, lp)
   sleep, 1000
}

47

Re: AHK: Асинхронный запуск скриптов

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

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

48

Re: AHK: Асинхронный запуск скриптов

Можно так сократить:

SetTitleMatchMode, 2
DetectHiddenWindows on
MyPID := DllCall("GetCurrentProcessId")
MyNumber := 1
WM_INFO := DllCall("RegisterWindowMessage", Str, "WM_INFO")
loop
{
   Text := "Это текст от скипта №" MyNumber
   wp := (StrLen(Text) * (A_IsUnicode ? 2 : 1)) << 16|MyPID
   lp := &Text
   PostMessage, WM_INFO, wp, lp,, check.ahk ahk_class AutoHotkey
   sleep, 1000
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

49

Re: AHK: Асинхронный запуск скриптов

А как правильно сделать так, чтобы следящий скрипт, после принятия информации от посылающего скрипта, отправлял посылающему скрипту ответ, что информация обработана?

50

Re: AHK: Асинхронный запуск скриптов

А в чём там сложность может быть? Принимает, и отправляет в ответ, а тот получает через OnMessage().

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

51

Re: AHK: Асинхронный запуск скриптов

Ясно. Просто не знал, могут ли случиться баги при обмене сообщениями во время очереди.

52

Re: AHK: Асинхронный запуск скриптов

Баги где угодно могут случиться, это от качества кода зависит.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

53

Re: AHK: Асинхронный запуск скриптов

Так будет правильно?
Следящий:

OnMessage(DllCall("RegisterWindowMessage", Str, "WM_INFO"), "WM_INFO_RECEIVER")
SetTitleMatchMode, 2
DetectHiddenWindows on

WM_INFO_RECEIVER(wp, lp)
{
   static PROCESS_VM_OPERATION := 0x8, PROCESS_VM_READ := 0x10
   Critical
   PID := wp & 0xFFFF
   Pointer := lp
   BuffSize := wp >> 16
   VarSetCapacity(LocalBuff, BuffSize, 0)
   
   if !hProc := DllCall("OpenProcess", UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ, Int, 0, UInt, PID, Ptr)
      Return
   
   res := DllCall("ReadProcessMemory", Ptr, hProc, Ptr, Pointer, Ptr, &LocalBuff, Ptr, BuffSize, Ptr, 0)
   DllCall("CloseHandle", Ptr, hProc)
   if !res
      Return
   
   CoordMode, ToolTip
   ToolTip % StrGet(&LocalBuff), A_ScreenWidth//2 - 100, A_ScreenHeight//2
   Sleep, 1000
   random, rand, 1, 2
   if rand = 1
      PostMessage, 0x5555,,,, test.ahk ahk_class AutoHotkey
   else
      PostMessage, 0x5554,,,, test.ahk ahk_class AutoHotkey
}

Отправляющий:

OnMessage(0x5555, "ErrorOn")
OnMessage(0x5554, "ErrorOff")
SetTitleMatchMode, 2
DetectHiddenWindows on
MyPID := DllCall("GetCurrentProcessId")
MyNumber := 1
WM_INFO := DllCall("RegisterWindowMessage", Str, "WM_INFO")
loop
{
   Text := A_Index
   wp := (StrLen(Text) * (A_IsUnicode ? 2 : 1)) << 16|MyPID
   lp := &Text
   PostMessage, WM_INFO, wp, lp,, check.ahk ahk_class AutoHotkey
   message := 0 
   while (message = 0)
      sleep 50
   if error = 1
      msgbox error
   else
      msgbox All Ok
}

ErrorOn()
{
   Global
   message := 1
   error := 1
}
      
ErrorOff()
{
   Global
   message := 1
   error := 0
}

54

Re: AHK: Асинхронный запуск скриптов

Не думаю. Если посылать сообщения с номером «от балды», нет смысла изначально пользоваться DllCall("RegisterWindowMessage", Str, "WM_INFO").

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

55

Re: AHK: Асинхронный запуск скриптов

Не понимаю, что значит от балды.

   Text := A_Index
   wp := (StrLen(Text) * (A_IsUnicode ? 2 : 1)) << 16|MyPID
   lp := &Text
   PostMessage, WM_INFO, wp, lp,, check.ahk ahk_class AutoHotkey

Это только для примера.
Скрипты будут отсылать принимающему в переменной Text интернет-ссылки+свое название.
Принимающий скрипт отправлять ссылку в скайп разным адрессатам в порядке очереди и если отправка произошла успешно, то отсылать обратно каждому скрипту соответствующее сообщение.

56

Re: AHK: Асинхронный запуск скриптов

От балды в смысле

      PostMessage, 0x5555,,,, test.ahk ahk_class AutoHotkey
      PostMessage, 0x5554,,,, test.ahk ahk_class AutoHotkey

0x5555 и 0x5554 — от балды и может с чем-то пересечься.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

57

Re: AHK: Асинхронный запуск скриптов

А как понять пересечься?
И как по-другому?
Я пример с справки брал.

58

Re: AHK: Асинхронный запуск скриптов

Ну, там упрощённый вариант. Если брать числа просто от фонаря — нет стопроцентной гарантии, что они уникальные (хоть и вероятность совпадения мала). Поэтому для создания своих сообщений принято пользоваться api-функцией RegisterWindowMessage(), которая гарантированно даёт нам уникальный номер сообщения.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

59

Re: AHK: Асинхронный запуск скриптов

Не получается. В чем ошибка?
check.ahk

SetTitleMatchMode, 2
DetectHiddenWindows on
WM_INFO := DllCall("RegisterWindowMessage", Str, "WM_INFO")
OnMessage(WM_INFO, "WM_INFO_RECEIVER")

WM_INFO_RECEIVER(wp, lp)
{
   static PROCESS_VM_OPERATION := 0x8, PROCESS_VM_READ := 0x10
   Critical
   PID := wp & 0xFFFF
   Pointer := lp
   BuffSize := wp >> 16
   VarSetCapacity(LocalBuff, BuffSize, 0)
   
   if !hProc := DllCall("OpenProcess", UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ, Int, 0, UInt, PID, Ptr)
      Return
   
   res := DllCall("ReadProcessMemory", Ptr, hProc, Ptr, Pointer, Ptr, &LocalBuff, Ptr, BuffSize, Ptr, 0)
   DllCall("CloseHandle", Ptr, hProc)
   if !res
      Return
   
   CoordMode, ToolTip
   ToolTip % StrGet(&LocalBuff), A_ScreenWidth//2 - 100, A_ScreenHeight//2
   Sleep, 1000
   random, rand, 1, 2
   if rand = 1
      PostMessage, WM_INFO, 1,,, test.ahk ahk_class AutoHotkey
   else
      PostMessage, WM_INFO, 0,,, test.ahk ahk_class AutoHotkey
}

test.ahk

SetTitleMatchMode, 2
DetectHiddenWindows on
MyPID := DllCall("GetCurrentProcessId")
WM_INFO := DllCall("RegisterWindowMessage", Str, "WM_INFO")
OnMessage(WM_INFO, "WM_INFO_RECEIVER")
loop
{
   Text := A_Index
   wp := (StrLen(Text) * (A_IsUnicode ? 2 : 1)) << 16|MyPID
   lp := &Text
   PostMessage, WM_INFO, wp, lp,, check.ahk ahk_class AutoHotkey
   message := 0 
   while (message = 0)
      sleep 50
   if error = 1
      msgbox error
   else
      msgbox All Ok
}


WM_INFO_RECEIVER(error)
{
   Global
   message := 1
   return, error
}

60

Re: AHK: Асинхронный запуск скриптов

WM_INFO нужно глобальной объявить в первом скрипте.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

61 (изменено: Malcev, 2016-02-24 20:37:29)

Re: AHK: Асинхронный запуск скриптов

А как вставить в проверяющий скрипт, алгоритм, в зависимости от результата которого:
1) продолжать производить какие-либо действия с каждым из полученных сообщений.
2) отправить всем скриптам в очереди сообщение и ждать новые сообщения.
По типу:

SetTitleMatchMode, 2
DetectHiddenWindows on
WM_INFO := DllCall("RegisterWindowMessage", Str, "WM_INFO")
OnMessage(WM_INFO, "WM_INFO_RECEIVER")

WM_INFO_RECEIVER(wp, lp)
{
   static PROCESS_VM_OPERATION := 0x8, PROCESS_VM_READ := 0x10
   Critical
   PID := wp & 0xFFFF
   Pointer := lp
   BuffSize := wp >> 16
   VarSetCapacity(LocalBuff, BuffSize, 0)
   
   if !hProc := DllCall("OpenProcess", UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ, Int, 0, UInt, PID, Ptr)
      Return
   
   res := DllCall("ReadProcessMemory", Ptr, hProc, Ptr, Pointer, Ptr, &LocalBuff, Ptr, BuffSize, Ptr, 0)
   DllCall("CloseHandle", Ptr, hProc)
   if !res
      Return
   
   CoordMode, ToolTip
   ToolTip % StrGet(&LocalBuff), A_ScreenWidth//2 - 100, A_ScreenHeight//2
   Sleep, 1000
   random, rand, 1, 2
   if rand = 1
   {
      ; различные действия....
      ; посылаем скрипту сообщение
      PostMessage, WM_INFO, 1,,, test.ahk ahk_class AutoHotkey
      ; Беремся за следующее в очереди
   }
   else
   {
      ; Посылаем всем скриптам в очереди сообщения и ждем новые.
      PostMessage, WM_INFO, 0,,, test.ahk ahk_class AutoHotkey
   }
}

62

Re: AHK: Асинхронный запуск скриптов

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

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

63 (изменено: Malcev, 2016-05-24 07:50:59)

Re: AHK: Асинхронный запуск скриптов

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

WM_INFO_RECEIVER(wp, lp)
{
   Global
   static PROCESS_VM_OPERATION := 0x8, PROCESS_VM_READ := 0x10
   Critical
   PID := wp & 0xFFFF
   Pointer := lp
   BuffSize := wp >> 16
   VarSetCapacity(LocalBuff, BuffSize, 0)
   
   if !hProc := DllCall("OpenProcess", UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ, Int, 0, UInt, PID, Ptr)
      Return
   
   res := DllCall("ReadProcessMemory", Ptr, hProc, Ptr, Pointer, Ptr, &LocalBuff, Ptr, BuffSize, Ptr, 0)
   DllCall("CloseHandle", Ptr, hProc)
   if !res
      Return
   
   %str% := StrGet(&LocalBuff)    ; динамическая глобальная переменная
   return
}

64

Re: AHK: Асинхронный запуск скриптов

Для безопасности лучше все используемые переменные кроме нужной объявить локальными:

WM_INFO_RECEIVER(wp, lp)
{
   local PID, Pointer, BuffSize, LocalBuff, hProc, res
   static PROCESS_VM_OPERATION := 0x8, PROCESS_VM_READ := 0x10
   Critical
   PID := wp & 0xFFFF
   Pointer := lp
   BuffSize := wp >> 16
   VarSetCapacity(LocalBuff, BuffSize, 0)
   
   if !hProc := DllCall("OpenProcess", UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ, Int, 0, UInt, PID, Ptr)
      Return
   
   res := DllCall("ReadProcessMemory", Ptr, hProc, Ptr, Pointer, Ptr, &LocalBuff, Ptr, BuffSize, Ptr, 0)
   DllCall("CloseHandle", Ptr, hProc)
   if !res
      Return
   
   %str% := StrGet(&LocalBuff)    ; динамическая глобальная переменная
   return
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

65

Re: AHK: Асинхронный запуск скриптов

На ahk 32bit передает не весь текст, если он слишком большой - порядка 50000 знаков.
Передает только половину.
Может тут ошибка в рассчетах?

wp := (StrLen(Text) * (A_IsUnicode ? 2 : 1)) << 16|MyPID

66

Re: AHK: Асинхронный запуск скриптов

Здесь вроде нет.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

67

Re: AHK: Асинхронный запуск скриптов

Вот посылающий:

SetTitleMatchMode, 2
DetectHiddenWindows on
WinGet, ParentHWND, id, check.ahk ahk_class AutoHotkey
MyPID := DllCall("GetCurrentProcessId")
MyNumber := 1
WM_INFO := DllCall("RegisterWindowMessage", Str, "WM_INFO")
fileread, text, 1.txt
wp := (StrLen(Text) * (A_IsUnicode ? 2 : 1)) << 16|MyPID
lp := &Text
DllCall("PostMessage", Ptr, ParentHWND, UInt, WM_INFO, Ptr, wp, Ptr, lp)
return

Вот принимающий:

#Persistent
OnMessage(DllCall("RegisterWindowMessage", Str, "WM_INFO"), "WM_INFO_RECEIVER")

WM_INFO_RECEIVER(wp, lp)
{
   static PROCESS_VM_OPERATION := 0x8, PROCESS_VM_READ := 0x10
   Critical
   PID := wp & 0xFFFF
   Pointer := lp
   BuffSize := wp >> 16
   VarSetCapacity(LocalBuff, BuffSize, 0)
   
   if !hProc := DllCall("OpenProcess", UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ, Int, 0, UInt, PID, Ptr)
      Return
   
   res := DllCall("ReadProcessMemory", Ptr, hProc, Ptr, Pointer, Ptr, &LocalBuff, Ptr, BuffSize, Ptr, 0)
   DllCall("CloseHandle", Ptr, hProc)
   if !res
      Return

   msgbox % clipboard := StrGet(&LocalBuff)
}

В той же папке создаю файл 1.txt - 50 kb.
На ahk 32 bit половина не доходит.

68

Re: AHK: Асинхронный запуск скриптов

А, хотя да, на 32 бита будет превышать размер пойнтера:

SetFormat, IntegerFast, H
MsgBox, % 50000 * 2 << 16
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

69

Re: AHK: Асинхронный запуск скриптов

Отправляй частями.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

70

Re: AHK: Асинхронный запуск скриптов

Это единственный вариант при использовании 32 бит Ahk?

71

Re: AHK: Асинхронный запуск скриптов

Здесь в wp посылается вместе PID и длина текста. Можно их как-то разделить, например, сначала послать одним сообщением только PID, это нужно ведь только один раз. Затем посылать длину уже без него, без сдвига.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

72 (изменено: Malcev, 2016-05-24 16:06:14)

Re: AHK: Асинхронный запуск скриптов

А можешь пример написать? А то я что-то не понимаю как отослать эти 2 сообщения.

73

Re: AHK: Асинхронный запуск скриптов

Посылающий и отправляющий скрипты постоянно работают, или перезапускаются?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

74 (изменено: Malcev, 2016-05-24 16:32:51)

Re: AHK: Асинхронный запуск скриптов

В основном постоянно.
Кстати, с WM_COPYDATA всё передается полностью.

75

Re: AHK: Асинхронный запуск скриптов

А запускаются только одновременно, или какой-то может перезапускаться отдельно?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

76

Re: AHK: Асинхронный запуск скриптов

На данный момент все запускаются одновременно.

77

Re: AHK: Асинхронный запуск скриптов

Посылающий:

SetTitleMatchMode, 2
DetectHiddenWindows on
WinGet, ParentHWND, id, check.ahk ahk_class AutoHotkey
MyPID := DllCall("GetCurrentProcessId")
WM_INFO := DllCall("RegisterWindowMessage", Str, "WM_INFO")
if !PidSent
	DllCall("PostMessage", Ptr, ParentHWND, UInt, WM_INFO, Ptr, MyPID, Ptr, 0), PidSent := 1
	
fileread, text, 1.txt
wp := StrLen(Text) * (A_IsUnicode ? 2 : 1)
lp := &Text
DllCall("PostMessage", Ptr, ParentHWND, UInt, WM_INFO, Ptr, wp, Ptr, lp)
return

Принимающий:

#Persistent
OnMessage(DllCall("RegisterWindowMessage", Str, "WM_INFO"), "WM_INFO_RECEIVER")

WM_INFO_RECEIVER(wp, lp)
{
   static PROCESS_VM_OPERATION := 0x8, PROCESS_VM_READ := 0x10, PID
   Critical
   if !PID  {
		PID := wp
		Return
	}
   Pointer := lp
   BuffSize := wp
   VarSetCapacity(LocalBuff, BuffSize, 0)
   
   if !hProc := DllCall("OpenProcess", UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ, Int, 0, UInt, PID, Ptr)
      Return
   
   res := DllCall("ReadProcessMemory", Ptr, hProc, Ptr, Pointer, Ptr, &LocalBuff, Ptr, BuffSize, Ptr, 0)
   DllCall("CloseHandle", Ptr, hProc)
   if !res
      Return

   msgbox % clipboard := StrGet(&LocalBuff)
}

Сначала запускать принимающий.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

78

Re: AHK: Асинхронный запуск скриптов

Не работает с несколькими посылающими скриптами.

79

Re: AHK: Асинхронный запуск скриптов

А у каждого из посылающих прописан в коде свой уникальный MyNumber?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

80

Re: AHK: Асинхронный запуск скриптов

Нет. А разве нужно? Мы ж не посылаем принимающему уникальный номер  MyNumber.
Вот 1-ый посылающий:

SetTitleMatchMode, 2
DetectHiddenWindows on
WinGet, ParentHWND, id, check.ahk ahk_class AutoHotkey
MyPID := DllCall("GetCurrentProcessId")
WM_INFO := DllCall("RegisterWindowMessage", Str, "WM_INFO")
if !PidSent
	DllCall("PostMessage", Ptr, ParentHWND, UInt, WM_INFO, Ptr, MyPID, Ptr, 0), PidSent := 1
	
fileread, text, 1.txt
wp := StrLen(Text) * (A_IsUnicode ? 2 : 1)
lp := &Text
DllCall("PostMessage", Ptr, ParentHWND, UInt, WM_INFO, Ptr, wp, Ptr, lp)
return

Вот второй:

SetTitleMatchMode, 2
DetectHiddenWindows on
WinGet, ParentHWND, id, check.ahk ahk_class AutoHotkey
MyPID := DllCall("GetCurrentProcessId")
WM_INFO := DllCall("RegisterWindowMessage", Str, "WM_INFO")
if !PidSent
	DllCall("PostMessage", Ptr, ParentHWND, UInt, WM_INFO, Ptr, MyPID, Ptr, 0), PidSent := 1
	
fileread, text, 2.txt
wp := StrLen(Text) * (A_IsUnicode ? 2 : 1)
lp := &Text
DllCall("PostMessage", Ptr, ParentHWND, UInt, WM_INFO, Ptr, wp, Ptr, lp)
return

Запускаем принимающий, потом первый посылающий - сообщение приходит, потом второй - сообщение не приходит.

81

Re: AHK: Асинхронный запуск скриптов

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

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

82

Re: AHK: Асинхронный запуск скриптов

А можешь, пожалуйста, изменить код с посылкой порядковых номеров вместо PID?

83

Re: AHK: Асинхронный запуск скриптов

Да, но PIDы всё равно нужно будет сначала передать, а потом их по номерам идентифицировать.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

84 (изменено: Malcev, 2016-05-25 00:13:01)

Re: AHK: Асинхронный запуск скриптов

Так может тогда вначале передать PID и A_ScriptHwnd либо A_ScriptFullPath для инициализации, чтоб не вписывать в каждый скрипт порядковый номер?

85

Re: AHK: Асинхронный запуск скриптов

А как потом в сообщениях узнавать, от какого скрипта они приходят?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

86

Re: AHK: Асинхронный запуск скриптов

Не знаю. Ну а разве есть разница между передачей порядкового номера прописанного в скрипте или его пути?

87 (изменено: teadrinker, 2016-05-25 01:35:12)

Re: AHK: Асинхронный запуск скриптов

А как ты строку хочешь передать в параметре сообщения? Там только цифры можно передавать. В 32-битном AHK в каждом параметре по 4 байта, т. е. от 0 до 0xFFFFFFFF. В одном из них у нас передаётся указатель на текст. Для чтения текста нам нужно знать PID процесса, в адресном пространстве которого этот указатель находится. Также нам нужно знать длину текста, чтобы зарезервировать буфер под него.

Можно, конечно, длину не посылать, и резервировать буфер максимально возможной длины. Этот вариант не очень экономичный, но реализуемый. Тогда нужно знать эту максимальную длину. Но, по-моему, проще прописывать в каждом скрипте уникальный номер, и отправлять его вместе с длиной. Если посылающих скриптов не больше пятнадцати, каждый номер займет всего 4 бита в параметре сообщения, остального места хватит, чтобы впихнуть длину вплоть до 268435455/2 знаков.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

88

Re: AHK: Асинхронный запуск скриптов

Становится яснее, а напиши, как это должно выглядеть с уникальным номером каждого из скриптов.

89

Re: AHK: Асинхронный запуск скриптов

Отправляющие:

SetTitleMatchMode, 2
DetectHiddenWindows on
WinGet, ParentHWND, id, check.ahk ahk_class AutoHotkey
MyNumber := 1  ; у каждого отправляющего скрипта должен быть свой номер, от 1 до 15
MyPID := DllCall("GetCurrentProcessId")
WM_INFO := DllCall("RegisterWindowMessage", Str, "WM_INFO")
if !PidSent
	DllCall("PostMessage", Ptr, ParentHWND, UInt, WM_INFO, Ptr, (MyNumber << 16)|MyPID, Ptr, 0), PidSent := 1
	
fileread, text, 1.txt
BuffLen := StrLen(Text) * (A_IsUnicode ? 2 : 1)
if (BuffLen > 0xFFFFFFF)  {
	MsgBox, Текст слишком длинный`, не будет отправлен!
	Return
}
wp := (MyNumber << 28) | BuffLen
lp := &Text
DllCall("PostMessage", Ptr, ParentHWND, UInt, WM_INFO, Ptr, wp, Ptr, lp)
return

Принимающий:

#Persistent
OnMessage(DllCall("RegisterWindowMessage", Str, "WM_INFO"), "WM_INFO_RECEIVER")

WM_INFO_RECEIVER(wp, lp)
{
   static PROCESS_VM_OPERATION := 0x8, PROCESS_VM_READ := 0x10, PidArray := []
   Critical
   if !lp  {
		PidArray[wp >> 16] := wp & 0xFFFF
		Return
	}
   Pointer := lp
   BuffSize := wp & 0xFFFFFFF
	PID := PidArray[wp >> 28]
   
   VarSetCapacity(LocalBuff, BuffSize, 0)
   if !hProc := DllCall("OpenProcess", UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ, Int, 0, UInt, PID, Ptr)
      Return
   
   res := DllCall("ReadProcessMemory", Ptr, hProc, Ptr, Pointer, Ptr, &LocalBuff, Ptr, BuffSize, Ptr, 0)
   DllCall("CloseHandle", Ptr, hProc)
   if !res
      Return

   msgbox % clipboard := StrGet(&LocalBuff)
}

Сначала запускать принимающий.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

90

Re: AHK: Асинхронный запуск скриптов

Вот так без номеров:

SetTitleMatchMode, 2
DetectHiddenWindows on
WinGet, ParentHWND, id, check.ahk ahk_class AutoHotkey
MyPID := DllCall("GetCurrentProcessId")
WM_INFO := DllCall("RegisterWindowMessage", Str, "WM_INFO")
	
fileread, text, 1.txt
BuffLen := StrLen(text) * (A_IsUnicode ? 2 : 1)
VarSetCapacity(Info, A_PtrSize*2, 0)
NumPut(&text, NumPut(BuffLen, Info))

wp := MyPID, lp := &Info
DllCall("PostMessage", Ptr, ParentHWND, UInt, WM_INFO, Ptr, wp, Ptr, lp)
return
#Persistent
OnMessage(DllCall("RegisterWindowMessage", Str, "WM_INFO"), "WM_INFO_RECEIVER")

WM_INFO_RECEIVER(wp, lp)
{
	static PROCESS_VM_OPERATION := 0x8, PROCESS_VM_READ := 0x10
	Critical
	PID := wp
	pInfo := lp

	if hProc := DllCall("OpenProcess", UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ, Int, 0, UInt, PID, Ptr)  {
		VarSetCapacity(LocalBuff, A_PtrSize * 2, 0)
		if DllCall("ReadProcessMemory", Ptr, hProc, Ptr, pInfo, Ptr, &LocalBuff, Ptr, A_PtrSize * 2, Ptr, 0)  {
			TextSize := NumGet(LocalBuff), pText := NumGet(&LocalBuff + A_PtrSize)
			VarSetCapacity(LocalBuff, TextSize, 0)
			res := DllCall("ReadProcessMemory", Ptr, hProc, Ptr, pText, Ptr, &LocalBuff, Ptr, TextSize, Ptr, 0)
		}
		DllCall("CloseHandle", Ptr, hProc)
	}
	if !res  {
		MsgBox, Ошибка при чтении данных
		Return
	}
	msgbox % clipboard := StrGet(&LocalBuff)
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

91 (изменено: Malcev, 2017-02-17 16:11:34)

Re: AHK: Асинхронный запуск скриптов

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

WinGet, ParentHWND, id, check.ahk ahk_class AutoHotkey
DllCall("PostMessage", Ptr, ParentHWND, UInt, WM_INFO, Ptr, wp, Ptr, lp)
WinGet, ParentHWND1, id, check1.ahk ahk_class AutoHotkey
DllCall("PostMessage", Ptr, ParentHWND1, UInt, WM_INFO, Ptr, wp, Ptr, lp)

92 (изменено: teadrinker, 2017-02-17 20:16:25)

Re: AHK: Асинхронный запуск скриптов

Не совсем понял эту идею:

WinGet, ParentHWND, id, check.ahk ahk_class AutoHotkey
DllCall("PostMessage", Ptr, ParentHWND, UInt, WM_INFO, Ptr, wp, Ptr, lp)

Зачем здесь PostMessage через DllCall?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

93

Re: AHK: Асинхронный запуск скриптов

Потому что ты так написал в 90 посте.

94

Re: AHK: Асинхронный запуск скриптов

А, да, точно.   Не имеет смысла, раз там есть DetectHiddenWindows, on. Завтра посмотрю, сейчас с телефона.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

95 (изменено: teadrinker, 2017-02-20 16:33:18)

Re: AHK: Асинхронный запуск скриптов

Malcev пишет:

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

Вообще не нужно создавать отдельные файлы, всё можно сгенерировать родительским файлом. Вот пример:

param = %1%

if (param != "")
   Menu, Tray, Icon, %A_AhkPath%, 2

#SingleInstance, Off
DetectHiddenWindows, On
OnMessage(WM_INFO := DllCall("RegisterWindowMessage", Str, "WM_INFO"), Func("WM_INFO_RECEIVER").Bind(param))

if (param = "") {
   children := []
   Loop 3  {
      Run, "%A_AhkPath%" "%A_ScriptFullPath%" "%A_Index%",,, PID
      children.Push(PID)
      while !WinExist("ahk_pid" PID)
         Sleep, 10
   }
   for k, v in children  {
      task%A_Index% := "Посчитать '3**" A_Index "'"
      SendMyMessage(WM_INFO, v, &task%A_Index%, StrLen(task%A_Index%))
   }
   OnExit(Func("CloseChildren").Bind(children))
}      

SendMyMessage(msg, PID, pStr, len)  {
   if A_IsUnicode
      len *= 2
   MyPID := DllCall("GetCurrentProcessId")
   wp := MyPID | (len << 16)
   lp := pStr
   SendMessage, msg, wp, lp,, ahk_pid %PID%
}

WM_INFO_RECEIVER(param, wp, lp, msg)  {
   Critical
   static reply, text
   PID := wp & 0xFFFF
   strSize := wp >> 16
   strPtr := lp
   str := ReadStringInAnotherProcess(PID, strPtr, strSize)
   
   if !param
      MsgBox, % str
   else  {
      RegExMatch(str, "'(.*)'", match)
      reply := "Ответ от скрипта " . param . ":`n" . match1 . " = " . ExecScript("FileAppend, % " match1 ", *")
      SendMyMessage(msg, PID, &reply, StrLen(reply))
   }
}
      
ReadStringInAnotherProcess(PID, addr, size)  {
   static PROCESS_VM_OPERATION := 0x8, PROCESS_VM_WRITE := 0x20, PROCESS_VM_READ := 0x10
   
   hProc := DllCall("OpenProcess", UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, Int, 0, UInt, PID, Ptr)
   VarSetCapacity(buff, size, 0)
   DllCall("ReadProcessMemory", Ptr, hProc, Ptr, addr, Ptr, &buff, Ptr, size, Int, 0)
   DllCall("CloseHandle", Ptr, hProc)
   Return StrGet(&buff)
}

CloseChildren(pids)  {
   for k, v in pids
      WinClose, ahk_pid %v%
}

ExecScript(Script)  {
   shell := ComObjCreate("WScript.Shell")
   exec := shell.Exec("AutoHotkey.exe /ErrorStdOut *")
   exec.StdIn.Write(script)
   exec.StdIn.Close()
   return exec.StdOut.ReadAll()
}

Здесь родительский скрипт сначала создаёт три дочерних из своего же файла, потом рассылает им строки, и получает ответы.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

96 (изменено: Malcev, 2017-02-19 23:15:19)

Re: AHK: Асинхронный запуск скриптов

Дочерние скрипты у меня уже имеются.
Вопрос в том, что если я впишу в посылаемый скрипт код с 91 поста - не будет ли в этом ошибки?
Потому как msdn пишет:

The RegisterWindowMessage function is typically used to register messages for communicating between two cooperating applications.

https://msdn.microsoft.com/en-us/librar … s.85).aspx

97

Re: AHK: Асинхронный запуск скриптов

Здесь «two» — это не ограничение, имеется в виду, что одно обменивается сообщениями с другим.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder