1 (изменено: Dworkin, 2017-11-10 21:44:43)

Тема: AHK: Работа с потоками autohotkey.dll

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

Сам autohotkey.dll скачал отсюда:
https://raw.githubusercontent.com/HotKe … Hotkey.dll
Библиотеки отсюда:
https://github.com/HotKeyIt/ahkdll-v2-r … ported.ahk
https://github.com/zhamlin/Macro/blob/m … Thread.ahk

НО их я закинул в папку lib где установлен autohotkey иначе через #include почему-то не работает.


Если так то из-за подгрузки еще одного AutoHotkey.dll выдается ошибка.

#Persistent
#NoEnv

codefromvar1 =
(
#Persistent
CoordMode, ToolTip, Screen 
var := 1
msgbox, 1
Loop {
	sleep 100
	var++
	ToolTip, var, 1024, 768, 1 
}
)

codefromvar2 =
(
#Persistent
CoordMode, ToolTip, Screen 
var2 := 1
msgbox, 2
Loop {
	sleep 100
	var2++
	ToolTip, var2, 1024, 780, 2 
}
)

AhkThread1 := AhkDllThread("AutoHotkey.dll")
AhkThread1.ahktextdll(codefromvar1)
AhkThread2 := AhkDllThread("AutoHotkey.dll")
AhkThread2.ahktextdll(codefromvar2)
return

Если же скопирую и переименную на AutoHotkey2.dll то теперь почему то не работает второй поток

#Persistent
#NoEnv

codefromvar1 =
(
#Persistent
CoordMode, ToolTip, Screen 
var := 1
msgbox, 1
Loop {
	sleep 100
	var++
	ToolTip, var, 1024, 768, 1 
}
)

codefromvar2 =
(
#Persistent
CoordMode, ToolTip, Screen 
var2 := 1
msgbox, 2
Loop {
	sleep 100
	var2++
	ToolTip, var2, 1024, 780, 2 
}
)

AhkThread1 := AhkDllThread("AutoHotkey.dll")
AhkThread1.ahktextdll(codefromvar1)
AhkThread2 := AhkDllThread("AutoHotkey2.dll")
AhkThread2.ahktextdll(codefromvar2)
return

Скажите пожалуйста как правильно?

2

Re: AHK: Работа с потоками autohotkey.dll

Удалось запустить одновременно два потока таким образом:

#Persistent
codefromvar1 =
(
#Persistent
CoordMode, ToolTip, Screen 
var := 1
msgbox, 1
Loop {
	sleep 100
	var++
	ToolTip, var, 1024, 768, 1 
}
)

codefromvar2 =
(
#Persistent
CoordMode, ToolTip, Screen 
var2 := 1
msgbox, 2
Loop {
	sleep 100
	var2++
	ToolTip, var2, 1024, 780, 2 
}
)

dllpath1 := "AutoHotkey.dll"
dllpath2 := "AutoHotkey2.dll"
DllCall("LoadLibrary","Str",dllpath1) ; Load the AutoHotkey module.
DllCall("LoadLibrary","Str",dllpath2) ; Load the AutoHotkey module.
DllCall(dllpath1 "\ahktextdll","Str",codefromvar1,"Str","","CDecl")
DllCall(dllpath2 "\ahktextdll","Str",codefromvar2,"Str","","CDecl")

но копировать каждый раз файл это время. Может есть другие идеи?

3 (изменено: YMP, 2017-11-11 12:03:39)

Re: AHK: Работа с потоками autohotkey.dll

Вариант, указанный в справке, — это использование MemoryModule. Он позволяет загружать одну и ту же DLL несколько раз. Но в AutoHotkey.dll оно не встроено, насколько я понимаю, надо скачивать соответствующую DLL'ку.

Хотя ниже написано вот что:

Internally AutoHotkey.dll COM Interface always uses MemoryModule to create a new thread

Не ясно, в общем.

4

Re: AHK: Работа с потоками autohotkey.dll

Dworkin пишет:

Может есть другие идеи?

Есть. Написать автору, почему его же код с последней длл выдаёт ошибку:

Loop 3
dll%A_Index%:=AhkDllThread(A_ScriptDir "\autohotkey.dll"),dll%A_Index%.ahkdll()

https://autohotkey.com/board/topic/5614 … hkexported

5 (изменено: Dworkin, 2017-11-12 04:47:15)

Re: AHK: Работа с потоками autohotkey.dll

Решил проблему конфликта загрузки несколько раз одного autohotkey.dll.
Нашел пост где был обновленный AhkDllThread который работает с x64 и он использовал #include <_MemoryLibrary>.
Короче нужны еще 3 библиотеки _MemoryLibrary, _Struct, sizeof.

Распишу для всех.
Все это в папку lib где установлен autohotkey:
https://github.com/HotKeyIt/ahkdll-v1-r … ibrary.ahk
https://github.com/HotKeyIt/ahkdll-v1-r … Struct.ahk
https://github.com/HotKeyIt/ahkdll-v1-r … sizeof.ahk
https://github.com/HotKeyIt/ahkdll-v2-r … ported.ahk

Обновленый AhkDllThread.ahk тоже в папку lib. Если папки нет, создайте ее:


#include <_MemoryLibrary>
AhkDllThread_IsH(){ ; FileGetVersionInfo Written by SKAN modified by HotKeyIt www.autohotkey.com/forum/viewtopic.php?p=233188#233188
 Static HexVal:="msvcrt\s" (A_IsUnicode?"w":"") "printf",AHK:=A_AhkPath?A_AhkPath:A_ScriptFullPath
 If ((FSz:=DllCall("Version\GetFileVersionInfoSize","Str",AHK,"UInt",0)) && VarSetCapacity(FVI,FSz,0) && VarSetCapacity(Trans,8*(A_IsUnicode?2:1)))
  && DllCall("Version\GetFileVersionInfo","Str",AHK,"Int",0,"UInt",FSz,"PTR",&FVI) 
  && DllCall("Version\VerQueryValue","PTR",&FVI,"Str","\VarFileInfo\Translation","PTR*",Translation,"UInt",0)
  && DllCall(HexVal,"Str",Trans,"Str","`%08X","UInt",NumGet(Translation+0))
  && DllCall("Version\VerQueryValue","PTR",&FVI,"Str","\StringFileInfo\" SubStr(Trans,-3) SubStr(Trans,1,4) "\InternalName","PTR*",InfoPtr,"UInt",0)
    Return StrGet(InfoPtr+0,DllCall("lstrlen" (A_IsUnicode?"W":"A"),"PTR",InfoPtr)) = "AutoHotkey_H"
				|| StrGet(InfoPtr+0,DllCall("lstrlen" (A_IsUnicode?"W":"A"),"PTR",InfoPtr)) = " "
}
AhkDllThread(dll="AutoHotkey.dll",obj=0){
  static init,ahkfunction,hLib,dllptr,libScript,ahkexec,DynaCall:="DynaCall", MemoryLoadLibrary:="MemoryLoadLibrary",MemoryFreeLibrary:="MemoryFreeLibrary"
      ,ResourceLoadLibrary:="ResourceLoadLibrary", MemoryGetProcAddress:="MemoryGetProcAddress"
  static AHK_H:=AhkDllThread_IsH()
  static base:={__Delete:"AhkDllThread"}
  static functions :="
(Join
ahkFunction:s=ssssssssss|ahkPostFunction:i=ssssssssss|
ahkdll:ut=sss|ahktextdll:ut=sss|ahkReady:|ahkReload:i|
ahkTerminate:i|addFile:ut=sucuc|addScript:ut=si|ahkExec:ui=s|
ahkassign:ui=ss|ahkExecuteLine:ut=utuiui|ahkFindFunc:ut=s|
ahkFindLabel:ut=s|ahkgetvar:s=sui|ahkLabel:ui=sui|ahkPause:s|ahkIsUnicode:
)"
  static AhkDllThreadfunc :="
(Join`r`n
" (!A_IsCompiled ? "#include <_MemoryLibrary>" : "") "
#Persistent
SetBatchLines,-1
#NoTrayIcon
Return
AhkDllThreadDLL(dll=""AutoHotkey.dll"",obj=0){
  static functions := ""ahkFunction:s=ssssssssss|ahkPostFunction:i=ssssssssss|""
              . ""ahkdll:ut=sss|ahktextdll:ut=sss|ahkReady:|ahkReload:i|""
              . ""ahkTerminate:i|addFile:ut=sucuc|addScript:ut=si|ahkExec:ui=s|""
              . ""ahkassign:ui=ss|ahkExecuteLine:ut=utuiui|ahkFindFunc:ui=s|""
              . ""ahkFindLabel:ui=s|ahkgetvar:s=sui|ahkLabel:ui=sui|ahkPause:s""
  static object
  If (dll=""0""){
    object:=""""
    return
  } else If (!FileExist(dll) && obj=0){
    MsgBox File: `%dll`% does not exist`, provide correct path for AutoHotkey.dll
    ExitApp
  }
  object:={"""":new _MemoryLibrary(obj?obj:dll)}
  Loop,Parse,functions,|
  {
    StringSplit,v,A_LoopField,:
    object[map="""" ? v1 : !InStr(map,v1) ? v1 : SubStr(map,InStr(map,v1)+StrLen(v1)+1,InStr(map,A_Space,0,InStr(map,v1)))]:=DynaCall(object[""""].GetProcAddress(v1),v2)
  }
  object.base:=Object(" (&base) ")
  return &object
}
)"
  If IsObject(dll){
    dll.ahkterminate()
    If !AHK_H {
      dll[""].Free(),dll:=""
    } else %MemoryFreeLibrary%(dll[""])
    return
  } else if (!FileExist(dll) && !A_IsCompiled){
    MsgBox File: %dll%`ndoes not exist`, provide correct path for AutoHotkey.dll
    ExitApp
  }
  If !AHK_H{
    If (init || ((hLib:=new _MemoryLibrary(A_IsCompiled?(dllptr:=DllCall("LockResource","ptr",DllCall("LoadResource","ptr",lib,"ptr",DllCall("FindResource","ptr",lib:=DllCall("GetModuleHandle","ptr",0,"ptr"),"str",dll,"ptr",10,"ptr"),"ptr"),"ptr")):dll)) && (Init:=hLib.GetProcAddress("ahktextdll")) && (!A_IsCompiled||LibScript:=(!(res:=DllCall("FindResource","ptr",lib:=DllCall("GetModuleHandle","ptr",0,"ptr"),"str",">AUTOHOTKEY SCRIPT<","ptr",10,"ptr"))?(res:=DllCall("FindResource","ptr",lib,"str",">AHK WITH ICON<","ptr",10,"ptr")):res)?StrGet(DllCall("LockResource","ptr",DllCall("LoadResource","ptr",lib,"ptr",res,"ptr"),"ptr"),DllCall("SizeofResource","ptr",lib,"ptr",res,"uint"),"UTF-8"):""))){
      If (ahkfunction || (DllCall(init,"Str",AhkDllThreadfunc "`n" LibScript,"Str","","Str","","Cdecl UInt") && (ahkfunction:=hLib.GetProcAddress("ahkFunction")) && (ahkExec:=hLib.GetProcAddress("ahkExec")))){
        return Object(0+DllCall(ahkfunction,"Str","AhkDllThreadDLL","Str",dll,"Str",A_IsCompiled?dllptr:"","Str","","Str","","Str","","Str","","Str","","Str","","Str","","Str","","CDecl Str"))
        ;reset internal return memory in autoHotkey.dll and release object
        ,DllCall(ahkfunction,"Str","AhkDllThreadDLL","Str","0","Str","","Str","","Str","","Str","","Str","","Str","","Str","","Str","","Str","","CDecl Str")
      } else {
        MsgBox Could not load script in %dll%
        Return 0
      }
    } else {
      MsgBox Could not load %dll%
      Return 0
    }
  }
  object:=IsObject(obj)?obj:{},object[""]:= A_IsCompiled ? %ResourceLoadLibrary%(dll) : %MemoryLoadLibrary%(dll)
  Loop,Parse,functions,|
  {
    StringSplit,v,A_LoopField,:
    object[map="" ? v1 : !InStr(map,v1) ? v1 : SubStr(map,InStr(map,v1)+StrLen(v1)+1,InStr(map,A_Space,0,InStr(map,v1)))]:=%DynaCall%(%MemoryGetProcAddress%(object[""],v1),v2)
  }
  return object,object.base:=base
}

И autohotkey.dll:
https://raw.githubusercontent.com/HotKe … Hotkey.dll

Очень важно! Что бы скомпилированный скрипт заработал надо:

FileInstall, AutoHotkey.dll,AutoHotkey.dll

И тогда этот код работает:

#Persistent
#NoEnv

codefromvar1 =
(
#Persistent
CoordMode, ToolTip, Screen 
var := 1
msgbox, 1
Loop {
	sleep 100
	var++
	ToolTip, var, 1024, 768, 1 
}
)

codefromvar2 =
(
#Persistent
CoordMode, ToolTip, Screen 
var2 := 1
msgbox, 2
Loop {
	sleep 100
	var2++
	ToolTip, var2, 1024, 780, 2 
}
)

AhkThread1 := AhkDllThread("AutoHotkey.dll")
AhkThread1.ahktextdll(codefromvar1)
AhkThread2 := AhkDllThread("AutoHotkey.dll")
AhkThread2.ahktextdll(codefromvar2)
return

6 (изменено: svoboden, 2017-11-12 04:05:25)

Re: AHK: Работа с потоками autohotkey.dll

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

7

Re: AHK: Работа с потоками autohotkey.dll

svoboden пишет:

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

Можно использовать функцию закачки и она не будет тормозить выполнение кода.
Например у меня скрипт обращается на сервер и пока ждет ответа, тупо висит. А с многоопытностью я могу посылать запросы на сервер подряд.

8 (изменено: KusochekDobra, 2017-11-12 04:28:20)

Re: AHK: Работа с потоками autohotkey.dll

А как например, закрыть поток, или обменяться данными? И где у Вас в основном примере, код получает доступ к папке "Lib", ведь нет ни одного инклуда? Или это какая-то хитрая сборка Autohotkey?

9 (изменено: Dworkin, 2017-11-12 04:35:40)

Re: AHK: Работа с потоками autohotkey.dll

KusochekDobra пишет:

А как например, закрыть поток? И где у Вас в основном примере, код получает доступ к папке "Lib", ведь нет ни одного инклуда?

Поток сам завершится после отработки кода, но есть свои нюансы.
Например


#Persistent
#NoEnv

codefromvar1 =
(
#Persistent
CoordMode, ToolTip, Screen 
var := 1
msgbox, 1
Loop 5 {
	sleep 1000
	var++
	ToolTip, var, 1024, 768, 1 
}

)

codefromvar2 =
(

CoordMode, ToolTip, Screen 
var2 := 1
msgbox, 2
Loop 5 {
	sleep 1000
	var2++
	ToolTip, var2, 1024, 780, 2 
}

)

AhkThread1 := AhkDllThread("AutoHotkey.dll")
AhkThread1.ahktextdll(codefromvar1)
AhkThread2 := AhkDllThread("AutoHotkey.dll")
AhkThread2.ahktextdll(codefromvar2)
return

Первый поток после отработки останется висеть так как #Persistent, а второй завершится. Либо если в коде потока есть #Persistent, вы можете после отработки кода написать exitapp.

codefromvar1 =
(
#Persistent
CoordMode, ToolTip, Screen 
var := 1
msgbox, 1
Loop 5 {
	sleep 1000
	var++
	ToolTip, var, 1024, 768, 1 
}
exitapp
)

тогда первый поток тоже завершится.

Создаете папку lib куда установлен autohotkey, закидываете туда инклуды(библиотеки) и autohotkey их автоматом использует. А файл autohotkey.dll я папку где скрипт или указываете путь.
А вот как обмениваться данными я не знаю. Знаю что например функции создания общей переменной или объекта для всех потоков и основного скрипта в ahk_l нет, но есть в ahk_h

10 (изменено: Malcev, 2017-11-12 06:10:23)

Re: AHK: Работа с потоками autohotkey.dll

Dworkin пишет:

Можно использовать функцию закачки и она не будет тормозить выполнение кода.
Например у меня скрипт обращается на сервер и пока ждет ответа, тупо висит. А с многоопытностью я могу посылать запросы на сервер подряд.

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

11 (изменено: Dworkin, 2017-11-12 06:14:22)

Re: AHK: Работа с потоками autohotkey.dll

Malcev пишет:

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

Потому что я об этом не знал)) Можете пожалуйста показать пример посылки нескольких пост запросов?
Многопоточность интересна, может еще понадобиться)

12

Re: AHK: Работа с потоками autohotkey.dll

https://autohotkey.com/docs/commands/UR … ToFile.htm
Когда мне понадобилась многопоточность я пробовал использовать autohotkey.dll, но мне показалось это неудобным.
В итоге с помощью teadrinkera создал следящий скрипт и кучу дочерних, которые передают информацию следящему.
http://forum.script-coding.com/viewtopic.php?id=10765

KusochekDobra пишет:

И где у Вас в основном примере, код получает доступ к папке "Lib", ведь нет ни одного инклуда?

Если скрипт находится в папке Lib с таким же названием, что и функция, то инклуд не нужен.

13 (изменено: Dworkin, 2017-11-12 07:10:32)

Re: AHK: Работа с потоками autohotkey.dll

Malcev пишет:

Когда мне понадобилась многопоточность я пробовал использовать autohotkey.dll, но мне показалось это неудобным.

Если вы пробывали многопоточность может у вас есть такие фукнции для AHK_L?
objShare
CriticalObject
CriticalSection
Может есть LowLevel.ahk? А то тот что я нашел почему-то крашит.

14

Re: AHK: Работа с потоками autohotkey.dll

Не, так далеко я не заходил.

15

Re: AHK: Работа с потоками autohotkey.dll

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

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

16 (изменено: Dworkin, 2017-11-12 18:04:25)

Re: AHK: Работа с потоками autohotkey.dll

YMP пишет:

морока с их версиями и т.д

Этим я уже заморочился и все что надо выложил сюда

Вот нашел функцию ObjShare.
https://hotkeyit.github.io/v2/docs/comm … jShare.htm

Пример:

LresultFromObject(obj){
	static IDispatch
	, set := VarSetCapacity(IDispatch, 16)
	, init := NumPut(0x46000000000000c0, NumPut(0x20400, IDispatch, "int64"), "int64")
	
	return DllCall("Oleacc.dll\LresultFromObject", ptr,&IDispatch, ptr,0, ptr,&obj, ptr)
}

global var := 0
class Test{
	Call(var){
		var++
		tooltip % var
	}
}

obj := new Test
lresult := LresultFromObject(obj)
threadCode =
(
	ObjectFromLresult(lresult){
		static IDispatch
		, set := VarSetCapacity(IDispatch, 16)
		, init := NumPut(0x46000000000000c0, NumPut(0x20400, IDispatch, "int64"), "int64")
		
		if DllCall("Oleacc.dll\ObjectFromLresult", ptr,lresult, ptr,&IDispatch, ptr,0, ptr,getvar(com:=0))
			throw "LResult Object could not be created"
		return ComObject(9,com,1)
	}

	obj := ObjectFromLresult(%lresult%)
	loop 5 {
		obj.call(A_Index)
		sleep 1000
	}
	msgbox, end thread.
	exitapp
)

ahkDll := "AutoHotkey.dll"
DllCall("LoadLibrary", str,ahkDll)
DllCall(ahkDll "\ahktextdll", str,threadCode, str,"", "CDecl")
sleep 7000
obj.call(999)

17

Re: AHK: Работа с потоками autohotkey.dll

Вообще, странная тема про эти потоки. Не показан пример, для чего оно надо и т.д.

18

Re: AHK: Работа с потоками autohotkey.dll

Так а разве вам не ответили в 7 посте?

19 (изменено: svoboden, 2017-11-15 21:08:07)

Re: AHK: Работа с потоками autohotkey.dll

Ответили, но тс говорил про какую-то многоопытность.

20

Re: AHK: Работа с потоками autohotkey.dll

Думаю, имелось в виду многопоточность.

21 (изменено: teadrinker, 2018-06-26 02:05:05)

Re: AHK: Работа с потоками autohotkey.dll

Dworkin пишет:

Если вы пробывали многопоточность может у вас есть такие фукнции для AHK_L?
objShare

Вот если ещё кому интересно, пример совместного использования объектов от lexikos:

Gui, +hwndhGui
Gui, Add, Text, w300 h200, Текст от главного скрипта
Gui, Show

myObj := Func("TestFunc").Bind(hGui)

GUID := CreateGUID()
ObjRegisterActive(myObj, GUID)
OnExit, Revoke

script =
(
Sleep 1000
x := ComObjActive("%GUID%")
x.Call("Текст от дочернего скрипта!")
)

ExecScript(script)
Return

GuiClose:
   ExitApp

Revoke:
   ObjRegisterActive(myObj, "")
   ExitApp
   
TestFunc(hGui, text)  {
   Gui, %hGui%:Default
   Gui, Font, s16 q5 c0055AA, calibri
   GuiControl, Font, Static1
   GuiControl,, Static1, % text
}

ObjRegisterActive(Object, CLSID, Flags := 0) {
   static cookieJar := {}
   if !CLSID  {
      if (( cookie := cookieJar.Delete(Object) ) != "")
         DllCall("oleaut32\RevokeActiveObject", UInt, cookie, Ptr, 0)
      return
   }
   if cookieJar[Object]
      throw Exception("Object is already registered", -1)
   VarSetCapacity(_clsid, 16, 0)
   if (hr := DllCall("ole32\CLSIDFromString", WStr, CLSID, Ptr, &_clsid)) < 0
      throw Exception("Invalid CLSID", -1, CLSID)
   hr := DllCall("oleaut32\RegisterActiveObject", Ptr, &Object, Ptr, &_clsid, UInt, Flags, UIntP, cookie, UInt)
   if hr < 0
      throw Exception(format("Error 0x{:x}", hr), -1)
   cookieJar[Object] := cookie
}

CreateGUID()
{
   VarSetCapacity(pguid, 16, 0)
   if !DllCall("ole32.dll\CoCreateGuid", Ptr, &pguid)  {
      size := VarSetCapacity(sguid, (38 << !!A_IsUnicode) + 1, 0)
      if DllCall("ole32.dll\StringFromGUID2", Ptr, &pguid, Ptr, &sguid, UInt, size)
         return StrGet(&sguid)
   }
}

ExecScript(script)
{
   shell := ComObjCreate("WScript.Shell")`
   exec := shell.Exec("AutoHotkey.exe /ErrorStdOut *")
   exec.StdIn.Write(script)
   exec.StdIn.Close()
   Return exec.ProcessID
}

Здесь дочерний скрипт использует FuncObject из родительского скрипта, и с его помощью производит изменения в GUI родительского скрипта.

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

22

Re: AHK: Работа с потоками autohotkey.dll

Получается, что этот вариант удобнее, чем с оконными сообщениями.

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

23

Re: AHK: Работа с потоками autohotkey.dll

Вроде удобнее, но я пока в реальной практике не применял. И почему-то этот способ не получил популярности, пост про ObjRegisterActive 2015 года, а я не видел, чтоб кто-то этим пользовался.

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

24

Re: AHK: Работа с потоками autohotkey.dll

Вроде работает, один объект на всех, куда уже удобнее.


Gui, +hwndhGui
Gui, Add, Text, w300 h200, Текст от главного скрипта
Gui, Show

myObj := {}
GUID := CreateGUID()
ObjRegisterActive(myObj, GUID)
myObj.fn := Func("TestFunc").Bind(hGui)
myObj.var2 := "Назначено из главного скрипта"

OnExit, Revoke

Loop 5
{
Sleep := 300 * A_Index
script =
(
#Persistent

Sleep %Sleep%
x := ComObjActive("%GUID%")
x.ExitFunc%A_Index% := Func("ExitFunc")
x.var1 := "Назначено из дочернего скрипта"
x.fn.Call("Текст от дочернего скрипта №%A_Index%")
MsgBox `% x.var2
Return

ExitFunc() { 
	SetTimer Exit, -1
}

Escape::
Exit: 
	ExitApp
)
ExecScript(script)
}

Sleep 1600 
MsgBox,,, % myObj.var1,2 
ExitApp
Return

Revoke: 
	Loop 5
		myObj["ExitFunc" A_Index].Call()  
	ObjRegisterActive(myObj, "")
	ExitApp
   
TestFunc(hGui, text)  {
   Gui, %hGui%:Default
   Gui, Font, s16 q5 c0055AA, calibri
   GuiControl, Font, Static1
   GuiControl,, Static1, % text
}

ObjRegisterActive(Object, CLSID, Flags := 0) {
   static cookieJar := {}
   if !CLSID  {
      if (( cookie := cookieJar.Delete(Object) ) != "")
         DllCall("oleaut32\RevokeActiveObject", UInt, cookie, Ptr, 0)
      return
   }
   if cookieJar[Object]
      throw Exception("Object is already registered", -1)
   VarSetCapacity(_clsid, 16, 0)
   if (hr := DllCall("ole32\CLSIDFromString", WStr, CLSID, Ptr, &_clsid)) < 0
      throw Exception("Invalid CLSID", -1, CLSID)
   hr := DllCall("oleaut32\RegisterActiveObject", Ptr, &Object, Ptr, &_clsid, UInt, Flags, UIntP, cookie, UInt)
   if hr < 0
      throw Exception(format("Error 0x{:x}", hr), -1)
   cookieJar[Object] := cookie
}

CreateGUID()
{
   VarSetCapacity(pguid, 16, 0)
   if !DllCall("ole32.dll\CoCreateGuid", Ptr, &pguid)  {
      size := VarSetCapacity(sguid, (38 << !!A_IsUnicode) + 1, 0)
      if DllCall("ole32.dll\StringFromGUID2", Ptr, &pguid, Ptr, &sguid, UInt, size)
         return StrGet(&sguid)
   }
}

ExecScript(script)
{
   shell := ComObjCreate("WScript.Shell")`
   exec := shell.Exec("AutoHotkey.exe *")
   exec.StdIn.Write(script)
   exec.StdIn.Close()
   Return exec.ProcessID
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

25 (изменено: serzh82saratov, 2018-07-01 03:22:58)

Re: AHK: Работа с потоками autohotkey.dll

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

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

26 (изменено: teadrinker, 2018-07-01 03:51:01)

Re: AHK: Работа с потоками autohotkey.dll

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

timer := ObjBindMethod(myClass, "test", "2")
SetTimer, % timer, -1000
timer := ObjBindMethod(myClass, "test", "3")
SetTimer, % timer, -2000
myClass.test("1")

class myClass
{
   test(param)  {
      SoundBeep
      Loop 10  {
         ToolTip % param "`n" A_Index
         Sleep, 300
      }
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

27

Re: AHK: Работа с потоками autohotkey.dll

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

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

28

Re: AHK: Работа с потоками autohotkey.dll

Да, и как ExecScript использовать в компилированном?

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

29

Re: AHK: Работа с потоками autohotkey.dll

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

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

30

Re: AHK: Работа с потоками autohotkey.dll

Error:  0x80070002 - Не удается найти указанный файл.
---> 097: exec := shell.Exec("AutoHotkey.exe *")

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

31

Re: AHK: Работа с потоками autohotkey.dll

А файл-то есть?

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

32 (изменено: serzh82saratov, 2018-07-02 23:47:46)

Re: AHK: Работа с потоками autohotkey.dll

Нет. Как можно запускать на пк где нет анк.

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

33 (изменено: teadrinker, 2018-07-02 23:54:46)

Re: AHK: Работа с потоками autohotkey.dll

Можно прицепить через FileInstall AutoHotkey.exe или AutoHotkey.dll. Теоретически, AutoHotkey.dll можно прямо из ресурса использовать, не выгружая, правда кода много будет.

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

34 (изменено: serzh82saratov, 2018-07-03 12:21:28)

Re: AHK: Работа с потоками autohotkey.dll

teadrinker пишет:

Теоретически, AutoHotkey.dll можно прямо из ресурса использовать, не выгружая

Вот это очень интересно. Записать dll в base64, и потом как то использовать?

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

35

Re: AHK: Работа с потоками autohotkey.dll

https://autohotkey.com/board/topic/7730 … rylibrary/

36

Re: AHK: Работа с потоками autohotkey.dll

Зачем в base64? Ты же не хочешь скрипт в 15.000 строк. Просто через FileInstall добавить в ресурсы, а потом, не выгружая, считать прямо из exe и использовать с помощью вышеупомянутой _MemoryLibrary.

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

37 (изменено: serzh82saratov, 2018-07-03 16:15:08)

Re: AHK: Работа с потоками autohotkey.dll

teadrinker пишет:

не выгружая, считать прямо из exe

Можешь поподробнее. В примерах только путь к "X:\AutoHotkey.dll".

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

38

Re: AHK: Работа с потоками autohotkey.dll

https://autohotkey.com/board/topic/7606 … de-builds/
Экзешники тоже можно запускать:
https://autohotkey.com/board/topic/8706 … -resource/

39

Re: AHK: Работа с потоками autohotkey.dll

А ты этим пользовался, там написано:

Those functions are not compatible with recent versions of AutoHotkey_L.

BinRun тоже 2012 года.

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

40

Re: AHK: Работа с потоками autohotkey.dll

serzh82saratov пишет:

В примерах только путь к "X:\AutoHotkey.dll".

Вот здесь пример, как из буфера загрузить:

FileRead,data,*c X:\AutoHotkey.dll
NewMemLib:=new _MemoryLibrary(&data)
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

41

Re: AHK: Работа с потоками autohotkey.dll

Это видел, но тут же файл указан, а как буфер создать из ресурса?

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

42

Re: AHK: Работа с потоками autohotkey.dll

Считать его в буфер. В ресурсе данные файла точно в таком же виде, как в исходном файле.

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

43

Re: AHK: Работа с потоками autohotkey.dll

serzh82saratov, когда-то гонял (какой год назад)- всё работало.

serzh82saratov пишет:

Those functions are not compatible with recent versions of AutoHotkey_L.

Это отвечено на вопрос топикстартера, почему те функции не работают в современном ahk.
И ниже приведен код для современного.

44

Re: AHK: Работа с потоками autohotkey.dll

teadrinker пишет:

В ресурсе данные файла точно в таком же виде, как в исходном файле.

Всё равно не догоняю, путь надо указать к самому скрипту, или как?

MalcevОк, спасибо за разъяснения.

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

45

Re: AHK: Работа с потоками autohotkey.dll

По первой ссылке Malcev'а код для считывания ресурса в буфер.

LoadScriptResource(Name, ByRef DataSize = 0, Type = 10)
{
    lib := DllCall("GetModuleHandle", "ptr", 0, "ptr")
    res := DllCall("FindResource", "ptr", lib, "str", Name, "ptr", Type, "ptr")
    DataSize := DllCall("SizeofResource", "ptr", lib, "ptr", res, "uint")
    hresdata := DllCall("LoadResource", "ptr", lib, "ptr", res, "ptr")
    return DllCall("LockResource", "ptr", hresdata, "ptr")
}

Здесь Name — название ресурса. Попробуй скомпилировать с FileInstall, увидишь в ResHacker, какое имя получается.

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

46

Re: AHK: Работа с потоками autohotkey.dll

Спасибо попробую, а для аналога ExecScript, запуска в новом процессе, надо инсталить AutoHotkey.exe и запускать через BinRun()? Нет пути проще, ведь интерпретатор уже есть в любом скомпилированном скрипте.

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

47

Re: AHK: Работа с потоками autohotkey.dll

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

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

48 (изменено: svoboden, 2018-07-03 18:57:45)

Re: AHK: Работа с потоками autohotkey.dll

ExecScript плохо работает. Были уже похожие темы:
http://forum.script-coding.com/viewtopi … 48#p124948;
https://autohotkey.com/board/topic/2357 … pipe/?st=0.

49

Re: AHK: Работа с потоками autohotkey.dll

ExecScript в обсуждаемом случае не нужен.

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

50

Re: AHK: Работа с потоками autohotkey.dll

teadrinker пишет:

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

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

51

Re: AHK: Работа с потоками autohotkey.dll

Есть такой ответ http://autohotkey.com/board/topic/87068 … /?p=613147, но у меня не запускается.

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

52

Re: AHK: Работа с потоками autohotkey.dll

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

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

53

Re: AHK: Работа с потоками autohotkey.dll

А по моей ссылке HotKeyIt разве не про запуск скрипта с помощью скомпилированного?

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

54

Re: AHK: Работа с потоками autohotkey.dll

Не обратил внимания, попозже посмотрю.

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

55

Re: AHK: Работа с потоками autohotkey.dll

serzh82saratov пишет:

А по моей ссылке HotKeyIt разве не про запуск скрипта с помощью скомпилированного?

Это для Autohotkey_H.

56

Re: AHK: Работа с потоками autohotkey.dll

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

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

57 (изменено: teadrinker, 2018-07-05 05:35:02)

Re: AHK: Работа с потоками autohotkey.dll

Вот так удалось запустить новый скрипт из скомпилированного с помощью AutoHotkeyMini.dll, добавленной в ресурсы через FieInstall:

; указать путь к AutoHotkey.dll/AutoHotkeyMini.dll битности, соответствующей скомпилированному файлу
FileInstall, D:\OneDrive\Scripts\AHK_H\AHK_Hv1\v1.1.29.01\ahkdll-v1-release-master\Win32w\AutoHotkeyMini.dll, % ""

#NoEnv
SetBatchLines, -1
#Include *i <_MemoryLibrary>

Gui, +hwndhGui
Gui, Add, Text, w300 h200, Текст от главного скрипта
Gui, Show

myObj := Func("TestFunc").Bind(hGui)
GUID := ObjRegisterActive(myObj)

script =
(
Sleep 1000
x := ComObjActive("%GUID%")
x.Call("Текст от дочернего скрипта!")
)

A_IsCompiled ? RunScriptWithResourceAutoHotkeyDll(script) : ExecScript(script)
Return

GuiClose:
   ExitApp

TestFunc(hGui, text)  {
   Gui, %hGui%:Default
   Gui, Font, s16 q5 c0055AA, calibri
   GuiControl, Font, Static1
   GuiControl,, Static1, % text
}

ExecScript(script)  {
   shell := ComObjCreate("WScript.Shell")`
   exec := shell.Exec("AutoHotkey.exe /ErrorStdOut *")
   exec.StdIn.Write(script)
   exec.StdIn.Close()
   Return exec.ProcessID
}

RunScriptWithResourceAutoHotkeyDll(script)  {
   hModule := DllCall("GetModuleHandle", Ptr, 0, Ptr)
   resNames := EnumResourceNames(hModule)
   for k, v in resNames
      if RegExMatch(v, "i)AutoHotkey(Mini)?\.dll", dllName)
         break
   if !dllName  {
      MsgBox, The resource with AutoHotkey.dll is not found!
      ExitApp
   }
   pRes := LoadScriptResource(hModule, v)
   CheckForDllBitness(pRes, dllName)
   MemLib := new _MemoryLibrary(pRes)
   DllCall(MemLib.GetProcAddress("ahktextdll"), Str, script, Str, "", Str, "")
   timer := Func("WatchThread").Bind(MemLib)
   SetTimer, % timer, 500
}

CheckForDllBitness(pRes, dllName)  {
   static x64 := 0x8664, x86 := 0x14C
   PEoffset := NumGet(pRes + 0x3C, "UInt")
   PE := NumGet(pRes + PEoffset + 4, "UShort")
   if ( (A_PtrSize = 8) ^ (PE = x64) )  {
      MsgBox, 16, Wrong %dllName% bitness, % "Your script bitness is " . (A_PtrSize = 8 ? "x64" : "x86") . "`n"
                                            . dllName . " bitness is " . (PE = x64 ? "x64" : "x86")      . "`n"
                                            . dllName . " bitness must correspond to script bitness!"
      ExitApp
   }
}

WatchThread(MemLib)  {
   if DllCall(MemLib.GetProcAddress("ahkReady"))
      Return
   SetTimer,, Delete
   MemLib.Free()
}

LoadScriptResource(lib, Name, ByRef DataSize = 0, Type = 10)  {
   res := DllCall("FindResource", Ptr, lib, Str, Name, Ptr, Type, Ptr)
   DataSize := DllCall("SizeofResource", Ptr, lib, Ptr, res, UInt)
   hresdata := DllCall("LoadResource", Ptr, lib, Ptr, res, Ptr)
   return DllCall("LockResource", Ptr, hresdata, Ptr)
}

EnumResourceNames(hModule)  {
   arrNames := []
   DllCall( "EnumResourceNames", Ptr, hModule, UInt, RT_RCDATA := 10
                               , Ptr, RegisterCallback("EnumResNameProc", "Fast", 4)
                               , Ptr, pNames := Object(arrNames) )
   ObjRelease(pNames)
   Return arrNames
}

EnumResNameProc(hModule, Type, Name, lp)  {
   obj := Object(lp)
   obj.Push( StrGet(Name) )
   Return 1
}

ObjRegisterActive(obj, register := true)  {
   static oInfo := {}
   if register  {
      if oInfo.HasKey(obj)
         Return oInfo[obj].CLSID
      CreateGuid(GUID)
      hReg := RegisterActiveObject(obj, &GUID)
      OnExit( Func(A_ThisFunc).Bind(hReg, false) )
      o := oInfo[obj] := {handle: hReg}
      Return o.CLSID := GetClsidString(&GUID)
   }
   else  {
      if IsObject(obj) && res := oInfo.Delete(obj)
         hReg := res.handle
      else  {
         for k, v in oInfo
            if (v.handle = obj && hReg := obj)
               break
      }
      ( hReg && RevokeObject(hReg) )
   }
}

CreateGuid(ByRef GUID)  {
   VarSetCapacity(GUID, 16, 0)
   DllCall("ole32\CoCreateGuid", Ptr, &GUID)
}

GetClsidString(pGUID)  {
   size := VarSetCapacity(sGUID, (38 << !!A_IsUnicode) + 1, 0)
   DllCall("ole32\StringFromGUID2", Ptr, pGUID, Ptr, &sGUID, UInt, size)
   Return StrGet(&sGUID)
}

RegisterActiveObject(obj, pGUID)  {
   hr := DllCall("oleaut32\RegisterActiveObject", Ptr, &obj, Ptr, pGUID, UInt, ACTIVEOBJECT_STRONG := 0, UIntP, hReg)
   if (hr != 0)
      throw Exception( Format("Error {:#x}", hr), -1 )
   Return hReg
}
   
RevokeObject(hReg)  {
   DllCall("oleaut32\RevokeActiveObject", UInt, hReg, Ptr, 0)
}

В FileInstall нужно указать путь к AutoHotkey.dll или AutoHotkeyMini.dll той же битности, в которую собираемся компилировать файл.
Скрипты _MemoryLibrary.ahk, _Struct.ahk и sizeof.ahk должны быть добавлены в пользовательскую библиотеку.

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

58

Re: AHK: Работа с потоками autohotkey.dll

С AutoHotkeyMini у меня ругается на хоткей, запустил с AutoHotkey.dll. Что интересно каждый поток создаёт свою иконку.
Но, в таком виде, после закрытия процесс компилированный под AHK_L остаётся висеть в диспетчере, с AHK_H нормально.

+ открыть спойлер

FileInstall, D:\AutoHotkey_H\1.1.29.1\Win32w\AutoHotkey.dll, % ""

#SingleInstance Force
#NoEnv 
SetBatchLines, -1
#Include *i <_MemoryLibrary>
OnExit, Revoke

Gui, +hwndhGui
Loop 5
	Gui, Add, Text, w300, Текст от главного скрипта
Gui, Show

myObj := {}
myObj.Func1 := Func("TestFunc").Bind(hGui)
GUID := ObjRegisterActive(myObj)

Loop 5
{
script =
(
#Persistent
Sleep 1111
id := %A_Index%
x := ComObjActive("%GUID%")
x.ExitFunc%A_Index% := Func("ExitFunc")
loop
{
	  ;	ToolTip %A_Index% - `%A_TickCount`%, 10, 50 * %A_Index%
	x.Func1.Call(id " - " A_TickCount, id) 
	Sleep 50
} 
Return

ExitFunc() { 
	SetTimer Exit, -1
}

^Esc::
Exit: 
	ExitApp
)
A_IsCompiled ? RunScriptWithResourceAutoHotkeyDll(script) : ExecScript(script)
}
Return

Revoke: 
	Loop 5
		try myObj["ExitFunc" A_Index].Call()   
	ObjRegisterActive(myObj, "")
	ExitApp

Escape::
GuiClose:
   ExitApp

TestFunc(hGui, text, id)  {  
   GuiControl,, Static%id%, % text
}

ExecScript(script)  {
   shell := ComObjCreate("WScript.Shell")`
   exec := shell.Exec("AutoHotkey.exe /ErrorStdOut *")
   exec.StdIn.Write(script)
   exec.StdIn.Close()
   Return exec.ProcessID
}

RunScriptWithResourceAutoHotkeyDll(script)  {
   hModule := DllCall("GetModuleHandle", Ptr, 0, Ptr)
   resNames := EnumResourceNames(hModule)
   for k, v in resNames
      {
	  ; MsgBox % v
	      if RegExMatch(v, "i)AutoHotkey(Mini)?\.dll", dllName)
	         break
      }
   if !dllName  {
      MsgBox, The resource with AutoHotkey.dll is not found!
      ExitApp
   }
   pRes := LoadScriptResource(hModule, v)
   CheckForDllBitness(pRes, dllName)
   MemLib := new _MemoryLibrary(pRes)
   DllCall(MemLib.GetProcAddress("ahktextdll"), Str, script, Str, "", Str, "")
   timer := Func("WatchThread").Bind(MemLib)
   SetTimer, % timer, 500
}

CheckForDllBitness(pRes, dllName)  {
   static x64 := 0x8664, x86 := 0x14C
   PEoffset := NumGet(pRes + 0x3C, "UInt")
   PE := NumGet(pRes + PEoffset + 4, "UShort")
   if ( (A_PtrSize = 8) ^ (PE = x64) )  {
      MsgBox, 16, Wrong %dllName% bitness, % "Your script bitness is " . (A_PtrSize = 8 ? "x64" : "x86") . "`n"
                                            . dllName . " bitness is " . (PE = x64 ? "x64" : "x86")      . "`n"
                                            . dllName . " bitness must correspond to script bitness!"
      ExitApp
   }
}

WatchThread(MemLib)  {
   if DllCall(MemLib.GetProcAddress("ahkReady"))
      Return
   SetTimer,, Delete
   MemLib.Free()
}

LoadScriptResource(lib, Name, ByRef DataSize = 0, Type = 10)  {
   res := DllCall("FindResource", Ptr, lib, Str, Name, Ptr, Type, Ptr)
   DataSize := DllCall("SizeofResource", Ptr, lib, Ptr, res, UInt)
   hresdata := DllCall("LoadResource", Ptr, lib, Ptr, res, Ptr)
   return DllCall("LockResource", Ptr, hresdata, Ptr)
}

EnumResourceNames(hModule)  {
   arrNames := []
   DllCall( "EnumResourceNames", Ptr, hModule, UInt, RT_RCDATA := 10
                               , Ptr, RegisterCallback("EnumResNameProc", "Fast", 4)
                               , Ptr, pNames := Object(arrNames) )
   ObjRelease(pNames)
   Return arrNames
}

EnumResNameProc(hModule, Type, Name, lp)  {
   obj := Object(lp)
   obj.Push( StrGet(Name) )
   Return 1
}

ObjRegisterActive(obj, register := true)  {
   static oInfo := {}
   if register  {
      if oInfo.HasKey(obj)
         Return oInfo[obj].CLSID
      CreateGuid(GUID)
      hReg := RegisterActiveObject(obj, &GUID)
      OnExit( Func(A_ThisFunc).Bind(hReg, false) )
      o := oInfo[obj] := {handle: hReg}
      Return o.CLSID := GetClsidString(&GUID)
   }
   else  {
      if IsObject(obj) && res := oInfo.Delete(obj)
         hReg := res.handle
      else  {
         for k, v in oInfo
            if (v.handle = obj && hReg := obj)
               break
      }
      ( hReg && RevokeObject(hReg) )
   }
}

CreateGuid(ByRef GUID)  {
   VarSetCapacity(GUID, 16, 0)
   DllCall("ole32\CoCreateGuid", Ptr, &GUID)
}

GetClsidString(pGUID)  {
   size := VarSetCapacity(sGUID, (38 << !!A_IsUnicode) + 1, 0)
   DllCall("ole32\StringFromGUID2", Ptr, pGUID, Ptr, &sGUID, UInt, size)
   Return StrGet(&sGUID)
}

RegisterActiveObject(obj, pGUID)  {
   hr := DllCall("oleaut32\RegisterActiveObject", Ptr, &obj, Ptr, pGUID, UInt, ACTIVEOBJECT_STRONG := 0, UIntP, hReg)
   if (hr != 0)
      throw Exception( Format("Error {:#x}", hr), -1 )
   Return hReg
}
   
RevokeObject(hReg)  {
   DllCall("oleaut32\RevokeActiveObject", UInt, hReg, Ptr, 0)
}

Так как здесь создаются потоки, не логичнее сделать этот пример с  LoadLibrary вместо ExecScript. И второй пример создающий процессы с ExecScript и BinRun.

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

59 (изменено: serzh82saratov, 2018-07-06 18:02:32)

Re: AHK: Работа с потоками autohotkey.dll

С FileInstall под AHK_H если компилировать с паролем, то при запуске вылетает ошибка.

Error: CONTINUABLE EXCEPTION_ACCESS_VIOLATION

Mouse and Keyboard hooks have been disabled.

  -  Press yes to exit thread and continue execution.
  -  Press no to continue thread (debug).
  -  Press cancel to exit application.

Exception was caused in thread id: 6952
Line: 1237

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

60 (изменено: teadrinker, 2018-07-06 18:16:10)

Re: AHK: Работа с потоками autohotkey.dll

serzh82saratov пишет:

после закрытия процесс компилированный под AHK_L остаётся висеть в диспетчере

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

DllCall(MemLib.GetProcAddress("ahkterminate")), MemLib.Free()
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

61

Re: AHK: Работа с потоками autohotkey.dll

То есть в AHK_H это делать не надо.

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

62

Re: AHK: Работа с потоками autohotkey.dll

Не знаю, не пробовал. Знаю, что AHK_H более глючный (или более требовательный к аккуратности при использовании памяти), и иногда возникают трудноотлавливаемые ошибки Error: CONTINUABLE EXCEPTION_ACCESS_VIOLATION.

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

63

Re: AHK: Работа с потоками autohotkey.dll

teadrinker пишет:

в новых ветках прописаны горячие клавиши, соответственно они не завершаются самостоятельно

Без горячих клавиш тоже самое.

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

64

Re: AHK: Работа с потоками autohotkey.dll

А разве мой пример тоже у тебя висит?

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

65

Re: AHK: Работа с потоками autohotkey.dll

serzh82saratov пишет:

Без горячих клавиш тоже самое.

Так у тебя там бесконечный цикл.

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

66 (изменено: serzh82saratov, 2018-07-06 18:52:07)

Re: AHK: Работа с потоками autohotkey.dll

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

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

67

Re: AHK: Работа с потоками autohotkey.dll

ExitApp в новых потоках не нужен, чтоб принудительно закрыть поток, нужно вызвать из основного

DllCall(MemLib.GetProcAddress("ahkterminate")), MemLib.Free()
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

68 (изменено: serzh82saratov, 2018-07-06 19:28:13)

Re: AHK: Работа с потоками autohotkey.dll

Всё, дошло.)
Как то долго создаются потоки и также закрываются, где то по пол секунды.

+ открыть спойлер

FileInstall, D:\AutoHotkey_H\1.1.29.1\Win32w\AutoHotkey.dll, % ""

#SingleInstance Force
#NoEnv 
SetBatchLines, -1
#Include *i <_MemoryLibrary>
OnExit, Revoke

Gui, +hwndhGui
Loop 5
	Gui, Add, Text, w300, Текст от главного скрипта
Gui, Show

myObj := {}
myThreads := {}
myObj.Func1 := Func("TestFunc").Bind(hGui)
GUID := ObjRegisterActive(myObj)

Loop 5
{
script =
(
; #NoTrayIcon
#Persistent
; Sleep 1111
id := %A_Index%
x := ComObjActive("%GUID%")
loop
{
	  ;	ToolTip %A_Index% - `%A_TickCount`%, 10, 50 * %A_Index%
	try x.Func1.Call(id " - " A_TickCount, id) 
	Sleep 50
}
Return

^Esc::
	ExitApp
)
A_IsCompiled ? RunScriptWithResourceAutoHotkeyDll(script, thread) : ExecScript(script)
myThreads[A_Index] := thread
}
Return

Revoke: 
	Loop 5
		{  
			If !!DllCall(myThreads[A_Index].GetProcAddress("ahkready"))
				DllCall(myThreads[A_Index].GetProcAddress("ahkterminate")), myThreads[A_Index].Free()
		}
	Sleep 100
	ExitApp

Escape::
GuiClose:
   ExitApp

TestFunc(hGui, text, id)  {  
   GuiControl,, Static%id%, % text
}

ExecScript(script)  {
   shell := ComObjCreate("WScript.Shell")`
   exec := shell.Exec("AutoHotkey.exe /ErrorStdOut *")
   exec.StdIn.Write(script)
   exec.StdIn.Close()
   Return exec.ProcessID
}

RunScriptWithResourceAutoHotkeyDll(script, byref MemLib)  {
   hModule := DllCall("GetModuleHandle", Ptr, 0, Ptr)
   resNames := EnumResourceNames(hModule)
   for k, v in resNames
      {
	  ; MsgBox % v "`n" k
	      if RegExMatch(v, "i)AutoHotkey(Mini)?\.dll", dllName)
	         break
      }
   if !dllName  {
      MsgBox, The resource with AutoHotkey.dll is not found!
      ExitApp
   }
   pRes := LoadScriptResource(hModule, v)
   CheckForDllBitness(pRes, dllName)
   MemLib := new _MemoryLibrary(pRes)
   DllCall(MemLib.GetProcAddress("ahktextdll"), Str, script, Str, "", Str, "")
   timer := Func("WatchThread").Bind(MemLib)
   SetTimer, % timer, 500
   
}

CheckForDllBitness(pRes, dllName)  {
   static x64 := 0x8664, x86 := 0x14C
   PEoffset := NumGet(pRes + 0x3C, "UInt")
   PE := NumGet(pRes + PEoffset + 4, "UShort")
   if ( (A_PtrSize = 8) ^ (PE = x64) )  {
      MsgBox, 16, Wrong %dllName% bitness, % "Your script bitness is " . (A_PtrSize = 8 ? "x64" : "x86") . "`n"
                                            . dllName . " bitness is " . (PE = x64 ? "x64" : "x86")      . "`n"
                                            . dllName . " bitness must correspond to script bitness!"
      ExitApp
   }
}

WatchThread(MemLib)  {
   if DllCall(MemLib.GetProcAddress("ahkReady"))
      Return
   SetTimer,, Delete
   MemLib.Free()
}

LoadScriptResource(lib, Name, ByRef DataSize = 0, Type = 10)  {
   res := DllCall("FindResource", Ptr, lib, Str, Name, Ptr, Type, Ptr)
   DataSize := DllCall("SizeofResource", Ptr, lib, Ptr, res, UInt)
   hresdata := DllCall("LoadResource", Ptr, lib, Ptr, res, Ptr)
   return DllCall("LockResource", Ptr, hresdata, Ptr)
}

EnumResourceNames(hModule)  {
   arrNames := []
   DllCall( "EnumResourceNames", Ptr, hModule, UInt, RT_RCDATA := 10
                               , Ptr, RegisterCallback("EnumResNameProc", "Fast", 4)
                               , Ptr, pNames := Object(arrNames) )
   ObjRelease(pNames)
   Return arrNames
}

EnumResNameProc(hModule, Type, Name, lp)  {
   obj := Object(lp)
   obj.Push( StrGet(Name) )
   Return 1
}

ObjRegisterActive(obj, register := true)  {
   static oInfo := {}
   if register  {
      if oInfo.HasKey(obj)
         Return oInfo[obj].CLSID
      CreateGuid(GUID)
      hReg := RegisterActiveObject(obj, &GUID)
      OnExit( Func(A_ThisFunc).Bind(hReg, false) )
      o := oInfo[obj] := {handle: hReg}
      Return o.CLSID := GetClsidString(&GUID)
   }
   else  {
      if IsObject(obj) && res := oInfo.Delete(obj)
         hReg := res.handle
      else  {
         for k, v in oInfo
            if (v.handle = obj && hReg := obj)
               break
      }
      ( hReg && RevokeObject(hReg) )
   }
}

CreateGuid(ByRef GUID)  {
   VarSetCapacity(GUID, 16, 0)
   DllCall("ole32\CoCreateGuid", Ptr, &GUID)
}

GetClsidString(pGUID)  {
   size := VarSetCapacity(sGUID, (38 << !!A_IsUnicode) + 1, 0)
   DllCall("ole32\StringFromGUID2", Ptr, pGUID, Ptr, &sGUID, UInt, size)
   Return StrGet(&sGUID)
}

RegisterActiveObject(obj, pGUID)  {
   hr := DllCall("oleaut32\RegisterActiveObject", Ptr, &obj, Ptr, pGUID, UInt, ACTIVEOBJECT_STRONG := 0, UIntP, hReg)
   if (hr != 0)
      throw Exception( Format("Error {:#x}", hr), -1 )
   Return hReg
}
   
RevokeObject(hReg)  {
   DllCall("oleaut32\RevokeActiveObject", UInt, hReg, Ptr, 0)
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

69

Re: AHK: Работа с потоками autohotkey.dll

ObjRegisterActive(myObj, "") не нужно, уже прописано в функции.

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

70

Re: AHK: Работа с потоками autohotkey.dll

Ок. Ещё добавил, а то процесс крашится если потока нет.

			If DllCall(myThreads[A_Index].GetProcAddress("ahkready"))
				DllCall(myThreads[A_Index].GetProcAddress("ahkterminate")), myThreads[A_Index].Free()
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

71

Re: AHK: Работа с потоками autohotkey.dll

Функция для запуска новых потоков с помощью AutoHotkey.dll:

#Persistent
#Include <_MemoryLibrary>
SetBatchLines, -1

FileInstall, D:\OneDrive\Scripts\AHK_H\AHK_Hv1\v1.1.29.01\ahkdll-v1-release-master\Win32w\AutoHotkeyMini.dll, % ""

ahkDll32 := "D:\OneDrive\Scripts\AHK_H\AHK_Hv1\v1.1.29.01\ahkdll-v1-release-master\Win32w\AutoHotkeyMini.dll"
ahkDll64 := "D:\OneDrive\Scripts\AHK_H\AHK_Hv1\v1.1.29.01\ahkdll-v1-release-master\x64w\AutoHotkeyMini.dll"

Loop 5
   RunNewThreadWithAutoHotkeyDll("MsgBox, Thread " . A_Index, A_IsCompiled ? "" : A_PtrSize = 8 ? ahkDll64 : ahkDll32)

Return

RunNewThreadWithAutoHotkeyDll(script, AutoHotkeyDllPath := "")  {
   static data, pData
   if !pData  {
      if FileExist(AutoHotkeyDllPath)  {
         FileRead, data, *c %AutoHotkeyDllPath%
         pData := &data
         SplitPath, AutoHotkeyDllPath, dllName
      }
      else if A_IsCompiled  {
         hModule := DllCall("GetModuleHandle", Ptr, 0, Ptr)
         resNames := EnumResourceNames(hModule)
         for k, v in resNames
            if RegExMatch(v, "i)AutoHotkey(Mini)?\.dll", dllName)
               break
         if dllName
            pData := LoadScriptResource(hModule, v)
      }
      if !dllName  {
         MsgBox, AutoHotkey.dll is not found!
         ExitApp
      }
      CheckForDllBitness(pData, dllName)
   }
   MemLib := new _MemoryLibrary(pData)
   DllCall(MemLib.GetProcAddress("ahktextdll"), Str, script, Str, "", Str, "")
   OnExit( Func("TerminateThread").Bind(MemLib) )
   timer := Func("WatchThread").Bind(MemLib)
   SetTimer, % timer, 500
}

CheckForDllBitness(pData, dllName)  {
   static x64 := 0x8664, x86 := 0x14C
   PEoffset := NumGet(pData + 0x3C, "UInt")
   PE := NumGet(pData + PEoffset + 4, "UShort")
   if !(PE = x64 || PE = x86)  {
      MsgBox, 16, Not valid dll, % dllName . " is not valid dll!"
      ExitApp
   }
   if ( (A_PtrSize = 8) ^ (PE = x64) )  {
      MsgBox, 16, Wrong %dllName% bitness, % "Your script bitness is " . (A_PtrSize = 8 ? "x64" : "x86") . "`n"
                                            . dllName . " bitness is " . (PE = x64 ? "x64" : "x86")      . "`n"
                                            . dllName . " bitness must correspond to script bitness!"
      ExitApp
   }
}

WatchThread(MemLib)  {
   if DllCall(MemLib.GetProcAddress("ahkReady"))
      Return
   SetTimer,, Delete
   MemLib.Free()
}

TerminateThread(MemLib)  {
   if ( MemLib.MM.init = 1 && DllCall(MemLib.GetProcAddress("ahkReady")) )
      DllCall(MemLib.GetProcAddress("ahkterminate")), MemLib.Free()
}

LoadScriptResource(lib, Name, ByRef DataSize = 0, Type = 10)  {
   res := DllCall("FindResource", Ptr, lib, Str, Name, Ptr, Type, Ptr)
   DataSize := DllCall("SizeofResource", Ptr, lib, Ptr, res, UInt)
   hresdata := DllCall("LoadResource", Ptr, lib, Ptr, res, Ptr)
   return DllCall("LockResource", Ptr, hresdata, Ptr)
}

EnumResourceNames(hModule)  {
   arrNames := []
   DllCall( "EnumResourceNames", Ptr, hModule, UInt, RT_RCDATA := 10
                               , Ptr, RegisterCallback("EnumResNameProc", "Fast", 4)
                               , Ptr, pNames := Object(arrNames) )
   ObjRelease(pNames)
   Return arrNames
}

EnumResNameProc(hModule, Type, Name, lp)  {
   obj := Object(lp)
   obj.Push( StrGet(Name) )
   Return 1
}

Если путь к AutoHotkey.dll не указан (или не найден) и файл скомпилирован, ищет dll в ресурсах. Следит за существованием созданных потоков, если поток завершается, освобождает память. При выходе закрывает оставшиеся потоки.

Скрипты _MemoryLibrary.ahk, _Struct.ahk и sizeof.ahk должны быть добавлены в пользовательскую библиотеку.

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

72

Re: AHK: Работа с потоками autohotkey.dll

serzh82saratov пишет:

Как то долго создаются потоки и также закрываются, где то по пол секунды.

С 64-битным интерпретатором гораздо быстрее.

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

73

Re: AHK: Работа с потоками autohotkey.dll

А можешь сделать свой пример с BinRun. Потоки выглядят пока очень глючно, с процессами надёжнее.

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

74

Re: AHK: Работа с потоками autohotkey.dll

BinRun на анк_l удалось запустить только некомпилированный,

BinRun(A_IsCompiled ? A_ScriptFullPath : A_AhkPath,"`nMsgBox %0%``n%1%``n%2%","Hello World!")

на анк_н не могу побороть ERROR: e_magic not found. И я уже говорил про то что если скомпилировать с ресурсом и паролем то вылетает CONTINUABLE EXCEPTION_ACCESS_VIOLATION.

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

75

Re: AHK: Работа с потоками autohotkey.dll

Попозже попробую, а какие глюки были с AutoHotkey.dll ?

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

76

Re: AHK: Работа с потоками autohotkey.dll

Если компилировать с паролем - CONTINUABLE EXCEPTION_ACCESS_VIOLATION.

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

77

Re: AHK: Работа с потоками autohotkey.dll

Так с AutoHotkey.dll не нужно под AHK_H компилировать.

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

78

Re: AHK: Работа с потоками autohotkey.dll

А тут мы что обсуждали? http://forum.script-coding.com/viewtopi … 73#p126673

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

79

Re: AHK: Работа с потоками autohotkey.dll

Я под AHK_L компилировал. Для AutoHotkey.dll без разницы, какой язык у вызывающего скрипта.

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

80

Re: AHK: Работа с потоками autohotkey.dll

teadrinker пишет:

какой язык у вызывающего скрипта

Всмысле?
Вот пример из справки, зачем тогда тут путь к длл?

AhkDllPath := A_ScriptDir "\AutoHotkeyMini.dll"
hModule := DllCall("LoadLibrary","Str",AhkDllPath)
DllCall(AhkDllPath "\ahktextdll","Str","Msgbox Hello World!","Str","","Str","","Cdecl UPTR")
MsgBox, End main thread
DllCall("FreeLibrary","PTR",hModule)
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

81

Re: AHK: Работа с потоками autohotkey.dll

Как это зачем путь? А с помощью чего мы новый поток запускаем?

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

82

Re: AHK: Работа с потоками autohotkey.dll

Так если нужен путь, как из скомпилированного запустить?

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

83

Re: AHK: Работа с потоками autohotkey.dll

В моём примере путь нужен только для FileInstall.

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

84 (изменено: serzh82saratov, 2018-07-11 20:45:43)

Re: AHK: Работа с потоками autohotkey.dll

teadrinker пишет:

Я под AHK_L компилировал.

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

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

85

Re: AHK: Работа с потоками autohotkey.dll

А зачем под H компилировать?

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

86

Re: AHK: Работа с потоками autohotkey.dll

Чтобы был один экзешник. А зачем под L компилировать?

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

87

Re: AHK: Работа с потоками autohotkey.dll

И главное пароль.

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

88

Re: AHK: Работа с потоками autohotkey.dll

Не понял. А если под L компилировать, не один экзешник получается?

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

89

Re: AHK: Работа с потоками autohotkey.dll

Пароль надо.

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

90

Re: AHK: Работа с потоками autohotkey.dll

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

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

91

Re: AHK: Работа с потоками autohotkey.dll

Прикольно, скинешь в личку?

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

92

Re: AHK: Работа с потоками autohotkey.dll

Не-а, не могу.

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

93

Re: AHK: Работа с потоками autohotkey.dll

Правильно, сначало надо продать за тыщу мильёнов.

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

94

Re: AHK: Работа с потоками autohotkey.dll

Зачем продавать удочку, если можно продавать рыбу?

95

Re: AHK: Работа с потоками autohotkey.dll

serzh82saratov, в этой теме teadrinker рассказал, как получить пароль:
http://forum.script-coding.com/viewtopic.php?id=13864
Пока, HotKeyIt не расскажет, как заменить генерацию пароля функцией, то в пароле нет никакого смысла.
А он что-то не спешит давать ответы на вопросы.
Даже про то, в чем нормально собрать его исходник он пока не дает никаких комментариев.

96

Re: AHK: Работа с потоками autohotkey.dll

Почему то перестало компилировать с моим паролем, только с паролем по умолчанию, у кого такое было?

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

97

Re: AHK: Работа с потоками autohotkey.dll

Malcev пишет:

Даже про то, в чем нормально собрать его исходник он пока не дает никаких комментариев.

Ну, если заглянуть в AutoHotkey.sln, то там это написано:

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.40629.0

Я в ней не пробовал, правда. А размер получается меньше, видимо, потому что отсутствуют два ресурса с длинными непонятными названиями в RCDATA (видно, если сравнить результат сборки со скачанным AutoHotkey_H).

98 (изменено: serzh82saratov, 2018-07-11 23:05:22)

Re: AHK: Работа с потоками autohotkey.dll

serzh82saratov пишет:

Почему то перестало компилировать с моим паролем, только с паролем по умолчанию, у кого такое было?

---------------------

Error at line 0.

Line Text: PK
Error: This line does not contain a recognized action.

The program will exit.
---------------------------
ОК   
---------------------------

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

99

Re: AHK: Работа с потоками autohotkey.dll

Так и должно быть. Изучай тему.

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

100 (изменено: teadrinker, 2018-07-13 21:27:20)

Re: AHK: Работа с потоками autohotkey.dll

Под любую версию, AHK_L или AHK_H со стандартным паролем:

#Persistent
#Include <_MemoryLibrary>
SetBatchLines, -1

FileInstall, D:\OneDrive\Scripts\AHK_H\AHK_Hv1\v1.1.29.01\ahkdll-v1-release-master\x64w\AutoHotkeyMini.dll, % ""

ahkDll32 := "D:\OneDrive\Scripts\AHK_H\AHK_Hv1\v1.1.29.01\ahkdll-v1-release-master\Win32w\AutoHotkeyMini.dll"
ahkDll64 := "D:\OneDrive\Scripts\AHK_H\AHK_Hv1\v1.1.29.01\ahkdll-v1-release-master\x64w\AutoHotkeyMini.dll"

Loop 5
   RunNewThreadWithAutoHotkeyDll("MsgBox, Thread " . A_Index, A_IsCompiled ? "" : A_PtrSize = 8 ? ahkDll64 : ahkDll32)

Return

RunNewThreadWithAutoHotkeyDll(script, AutoHotkeyDllPath := "")  {
   static data, pData, threads := []
        , _ := OnExit(Func("RunNewThreadWithAutoHotkeyDll").Bind("", ""))
        , timer := Func("RunNewThreadWithAutoHotkeyDll").Bind("watchThreads")
        
   if (script = "")  {                                 ; OnExit
      for k, v in threads
         TerminateThread(v)
      Return
   }
   
   if (script = "watchThreads")  {                     ; watchThreads timer
      Critical
      newThreads := []
      for k, v in threads
         DllCall(v.GetProcAddress("ahkReady")) ? newThreads.Push(v) : v.Free()
      
      threads := newThreads
      if !ObjMaxIndex(threads)
         SetTimer,, Off
      Critical Off
      Return
   }
      
   if !pData  {
      if FileExist(AutoHotkeyDllPath)  {
         FileRead, data, *c %AutoHotkeyDllPath%
         pData := &data
         SplitPath, AutoHotkeyDllPath, dllName
      }
      else if A_IsCompiled  {
         hModule := DllCall("GetModuleHandle", Ptr, 0, Ptr)
         resNames := EnumResourceNames(hModule)
         for k, v in resNames
            if RegExMatch(v, "i)AutoHotkey(Mini)?\.dll", dllName)
               break
         if dllName  {
            pData := LoadScriptResource(hModule, v, size)
            try Func("UnZipRawMemory").Call(pData, size, data, "AutoHotkey")
            ( data && pData := &data )
         }
      }
      if !dllName  {
         MsgBox, AutoHotkey.dll is not found!
         ExitApp
      }
      CheckForDllBitness(pData, dllName)
   }
   MemLib := new _MemoryLibrary(pData)
   DllCall(MemLib.GetProcAddress("ahktextdll"), Str, script, Str, "", Str, "")
   threads.Push(MemLib)
   if ObjMaxIndex(threads) = 1
      SetTimer, % timer, 500
}

CheckForDllBitness(pData, dllName)  {
   static x64 := 0x8664, x86 := 0x14C
   PEoffset := NumGet(pData + 0x3C, "UInt")
   PE := NumGet(pData + PEoffset + 4, "UShort")
   if !(PE = x64 || PE = x86)  {
      MsgBox, 16, Not valid dll, % dllName . " is not valid dll!"
      ExitApp
   }
   if ( (A_PtrSize = 8) ^ (PE = x64) )  {
      MsgBox, 16, Wrong %dllName% bitness, % "Your script bitness is " . (A_PtrSize = 8 ? "x64" : "x86") . "`n"
                                            . dllName . " bitness is " . (PE = x64 ? "x64" : "x86")      . "`n"
                                            . dllName . " bitness must correspond to script bitness!"
      ExitApp
   }
}

TerminateThread(MemLib)  {
   if ( MemLib.MM.init = 1 && DllCall(MemLib.GetProcAddress("ahkReady")) )
      DllCall(MemLib.GetProcAddress("ahkterminate")), MemLib.Free()
}

LoadScriptResource(lib, Name, ByRef DataSize = 0, Type = 10)  {
   res := DllCall("FindResource", Ptr, lib, Str, Name, Ptr, Type, Ptr)
   DataSize := DllCall("SizeofResource", Ptr, lib, Ptr, res, UInt)
   hresdata := DllCall("LoadResource", Ptr, lib, Ptr, res, Ptr)
   return DllCall("LockResource", Ptr, hresdata, Ptr)
}

EnumResourceNames(hModule)  {
   arrNames := []
   DllCall( "EnumResourceNames", Ptr, hModule, UInt, RT_RCDATA := 10
                               , Ptr, RegisterCallback("EnumResNameProc", "Fast", 4)
                               , Ptr, pNames := Object(arrNames) )
   ObjRelease(pNames)
   Return arrNames
}

EnumResNameProc(hModule, Type, Name, lp)  {
   obj := Object(lp)
   obj.Push( StrGet(Name) )
   Return 1
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder