-
Notifications
You must be signed in to change notification settings - Fork 72
/
RemoteInvocation.ahk
135 lines (113 loc) · 4.42 KB
/
RemoteInvocation.ahk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
; Link: https://www.autohotkey.com/boards/viewtopic.php?f=6&t=55165
; Author: Capn Odin
; Date:
; for: AHK_L
; Introduction[hr][/hr]
; I believe this already exists as I thought I would try making it after hearing of a similar library.
; The script can call functions and set global variable in other scripts that also includes RemoteInvocation.
; Limitations: only strings are supported as arguments. Additionally a script that includes this will be persistent.
/* example
DetectHiddenWindows, On
SetTitleMatchMode, 2
Sleep, 1000
lorem_ipsum =
(
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean fermentum risus id tortor. Integer pellentesque quam vel velit. Praesent id justo in neque elementum ultrices. Nunc tincidunt ante vitae massa.
Etiam sapien elit, consequat eget, tristique non, venenatis quis, ante. Duis ante orci, molestie vitae vehicula venenatis, tincidunt ac pede. Maecenas lorem. Nam sed tellus id magna elementum tincidunt.
Integer pellentesque quam vel velit. Nullam dapibus fermentum ipsum. Phasellus rhoncus. Etiam dui sem, fermentum vitae, sagittis id, malesuada in, quam.
)
loop 30 {
str .= lorem_ipsum
}
InvokeFunction("Function.ahk", "fun", str)
*/
InvokeVariable(title, variable, value) {
text := variable "=" value
RemotePost(0x1fe0, text, title)
}
InvokeFunction(title, function, parameters*) {
text := function "("
if(parameters.Length()) {
for i, parameter in parameters {
text .= StrReplace(parameter, ",", "#¤#") ","
}
text := SubStr(text, 1, -1)
}
text .= ")"
RemotePost(0x1fe1, text, title)
}
RemoteInvocationVariable(pID, lParam, msg, hwnd) {
Critical
Static __ := OnMessage(0x1fe0, "RemoteInvocationVariable")
expression := ReadPointer(pID, lParam)
if(InStr(expression, "=")) {
args := StrSplit(expression, "=", 2)
if(args[1] != "") {
var := RegExReplace(args[1], "\s", "")
%var% := args[2]
} else {
RemotePostError("Can't set a variable without a name", "ahk_pid " pID)
}
} else {
RemotePostError("Malformed argument, lacking an equal sign", "ahk_pid " pID)
}
}
RemoteInvocationFunction(pID, lParam, msg, hwnd) {
Critical
Static __ := OnMessage(0x1fe1, "RemoteInvocationFunction")
expression := ReadPointer(pID, lParam)
args := StrSplit(expression, "(", 2)
if(IsFunc(args[1])) {
fun := Func(args[1])
arguments := __RestoreCommas(StrSplit(SubStr(args[2], 1, -1), ","))
if(fun.MinParams <= arguments.Length() && (fun.IsVariadic || fun.MaxParams >= arguments.Length())) {
fun.Call(arguments*)
} else {
RemotePostError(__FunctionErrorMessage(fun, arguments), "ahk_pid " pID)
}
} else {
RemotePostError("Function """ args[1] """ does not exist", "ahk_pid " pID)
}
}
__RestoreCommas(arguments) {
loop % arguments.Length() {
arguments[A_Index] := StrReplace(arguments[A_Index], "#¤#", ",")
}
return arguments
}
__FunctionErrorMessage(fun, arguments) {
return (arguments.Length() < fun.MinParams ? "Only " : "") arguments.Length() " argument(s) passed to function """ fun.Name """, which expects " fun.MinParams " arguments" (fun.MaxParams - fun.MinParams ? " with additional " fun.MaxParams - fun.MinParams " (optional) argument(s)." : ".")
}
RemoteInvocationError(pID, lParam, msg, hwnd) {
Critical
Static __ := OnMessage(0x1fe2, "RemoteInvocationError")
msg := ReadPointer(pID, lParam)
DetectHiddenWindows, On
WinGetTitle, title, % "ahk_pid " pID
RegExMatch(title, "\\\K[^\\]+.ahk", file)
MsgBox, 0x30, % "Remote Invocation Error - " A_ScriptName, % "Error: " msg "`nin """ (file ? file : title) """"
}
ReadPointer(pID, lpBaseAddress){
Static PROCESS_ALL_ACCESS := 0x1F0FFF, nSize := 50
hProcess := DllCall("OpenProcess", "UInt", PROCESS_ALL_ACCESS, "UInt", True, "UInt", pID)
VarSetCapacity(lpBuffer, nSize)
VarSetCapacity(lpNumberOfBytesRead, 8)
DllCall("ReadProcessMemory", "UPtr", hProcess, "UPtr", lpBaseAddress, "UPtr", &lpBuffer, "UInt", nSize, "UPtr", &lpNumberOfBytesRead)
msgobj := StrSplit(StrGet(&lpBuffer, "UTF-16"), "#")
VarSetCapacity(lpBuffer, msgobj[1]+0, 0)
DllCall("ReadProcessMemory", "UPtr", hProcess, "UPtr", msgobj[2]+0, "UPtr", &lpBuffer, "UInt", msgobj[1]+0, "UPtr", &lpNumberOfBytesRead)
Return StrGet(&lpBuffer, "UTF-16")
}
RemotePostError(text, title) {
RemotePost(0x1fe2, text, title)
}
RemotePost(msgNum, text, title) {
Static mem := "", mem2 := ""
mem2 := text
mem := VarSetCapacity(mem2, -1) "#" &mem2
PostMessage, % msgNum, % GetPID(), % &mem, , % title
}
GetPID() {
Process, Exist
return ErrorLevel
}