Use autohotkey.exe or autohotkey.dll of v2 to load the library files, and returns an object which can be used as follows:
Code: Select all
; load v2 librarys
lib := import_v2lib("LibPath", "AHK.exe")
lib := import_v2lib(["Lib1Path", "Lib2Path"], "AHK.exe")
lib := import_v2lib("test(a){`n}", "AHK.dll")
; Call a function named 'Function' in the target library:
lib.Function.Call(params)
lib.Function.Call
; Retrieve a global variable:
value := lib["VarName"]
value := lib.VarName
; Set a global variable:
lib["VarName"] := value
lib.VarName := value
; Create a class instance
value := lib["ClassName"].Call(params)
value := lib.ClassName.NestedClass.Call(params)
; set __Item prop `a := [[1]]`
lib.SetItem(lib.a[1], 22222, 1) ; a[1][1] := 22222
; get __Item prop
lib.GetItem(lib.a[1], 1) ; 22222
Code: Select all
/**
/**
* import ahk v2 library to v1. It can call v2 functions and classes, read and modify global variables.
*
* - import v2 lib `v2 := import_v2lib("gdip_all.ahk", "ahkv2.exe")`
* - create a class instance `v2["classname"].Call(params)` or `v2.classname.Call(params)`
* - call a functions `v2.funcname.Call(params)`
* - set a global variable `v2.varname := "str"` or `v2["varname"] := {}`
* - retrieve a global variable `value := v2["varname"]` or `value := v2.varname`
* - set __Item prop `v2.SetItem(v2object, value, param1 ...)`
* - get __Item prop `v2.GetItem(v2object, param1 ...)`
*
* @param pathsorcode The paths of the include script files or ahk v2 code. `Array or String`
* @param ahkv2runtime The path of the AutoHotkey v2 runtime (AutoHotkey.exe or AutoHotkey.dll).
*/
import_v2lib(pathsorcode, ahkv2runtime) {
static IDispatch, _ := (VarSetCapacity(IDispatch, 16), NumPut(0x46000000000000c0, NumPut(0x20400, IDispatch, "int64"), "int64"))
lresult := DllCall("oleacc\LresultFromObject", "ptr", &IDispatch, "ptr", 0, "ptr", &(client := { proxy: 0 }), "ptr")
if !FileExist(ahkv2runtime) {
; free com marshal on fail
DllCall("oleacc\ObjectFromLresult", "ptr", lresult, "ptr", &IDispatch, "ptr", 0, "ptr*", idsp := 0), ObjRelease(idisp)
throw Exception("AutoHotkey v2 runtime isn't exist")
}
if IsObject(pathsorcode) {
t := pathsorcode, pathsorcode := ""
for i, p in t
pathsorcode .= "`n#include " p
}
v2script := Format("
(
#NoTrayIcon
class __AHKv2LibHelper {
static __New() {
Persistent
NumPut('int64', 0x20400, 'int64', 0x46000000000000c0, IDispatch := Buffer(16))
DllCall('oleacc\ObjectFromLresult', 'ptr', {}, 'ptr', IDispatch, 'ptr', 0, 'ptr*', &idisp := 0)
ComObjFromPtr(idisp).proxy := this()
}
__Get(name, params) => params.Length ? %name%[params*] : %name%
__Set(name, params, value) {
global
if params.Length
%name%[params*] := value
else %name% := value
}
GetItem(obj, params*) => obj[params*]
SetItem(obj, value, params*) => obj[params*] := value
__Delete() => SetTimer(ExitApp, -1)
}
{}
)", lresult, FileExist(pathsorcode) ? "#include " pathsorcode : pathsorcode)
if (ahkv2runtime ~= "i)\.dll$") {
if (!DllCall("GetModuleHandle", "str", ahkv2runtime) && !DllCall("LoadLibrary", "str", ahkv2runtime)) {
DllCall("oleacc\ObjectFromLresult", "ptr", lresult, "ptr", &IDispatch, "ptr", 0, "ptr*", idsp := 0), ObjRelease(idisp)
throw Exception("load AutoHotkey.dll fail")
}
if !(threadID := DllCall(ahkv2runtime "\NewThread", "str", v2script, "str", "", "str", "", "cdecl uint")) {
DllCall("oleacc\ObjectFromLresult", "ptr", lresult, "ptr", &IDispatch, "ptr", 0, "ptr*", idsp := 0), ObjRelease(idisp)
throw Exception("Failed to load script")
}
while !client.proxy
Sleep 10
} else {
exec := ComObjCreate("WScript.Shell").Exec("""" ahkv2runtime """ /ErrorStdOut *")
exec.StdIn.Write(v2script), exec.StdIn.Close()
while (exec.Status = 0 && !client.proxy)
Sleep 10
if (exec.Status != 0) {
ex := Exception("Failed to load script")
if (RegExMatch(err := exec.StdErr.ReadAll(), "Os)(.*?) \((\d+)\) : ==> (.*?)(?:\s*Specifically: (.*?))?\R?$", m))
ex.Message .= "`n`nReason:`t" m[3] "`nLine text:`t" m[4] "`nFile:`t" m[1] "`nLine:`t" m[2]
DllCall("oleacc\ObjectFromLresult", "ptr", lresult, "ptr", &IDispatch, "ptr", 0, "ptr*", idsp := 0), ObjRelease(idisp)
throw ex
}
}
return client.proxy
}