51

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

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

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

52

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

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

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

53

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

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

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

54

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

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

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

55

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

serzh82saratov пишет:

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

Это для Autohotkey_H.

56

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

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

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

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
Skype dmitry_fiveg

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
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

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
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

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
Skype dmitry_fiveg

61

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

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

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

62

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

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

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

63

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

teadrinker пишет:

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

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

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

64

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

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

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

65

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

serzh82saratov пишет:

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

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

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

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

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

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

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

67

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

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

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

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
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

69

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

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

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

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
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

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
Skype dmitry_fiveg

72

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

serzh82saratov пишет:

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

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

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

73

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

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

По вопросам возмездной помощи пишите письма
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

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
OS: Win7x64, AutoHotkey_L v1.1.29.01 (Unicode 32-bit).

75

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

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

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