增加的全局变量:
h_history 即使重启也不会损毁的记录对象
h_Caller 调用者的名字
h_CallerPid
h_CallerId
h_CallerHwnd
Code: Select all
f:=[]
loop 100
s.="asdfsafsafsafsafsafasfsaf"
loop 1000
f.Push(l:=[s])
AhkRun("ObjTree(h_history)`nMsgBox `% `"Reload `" `nReload()",,[f,f,f])
Code: Select all
AhkRun(Script,Title:="",Args:="",Tray:="",Path:=""){
static fox:=[]
if Type(Script)="Integer"
Return c:=Struct("ULONG_PTR dwData,DWORD cbData,PVOID lpData"),Script=1
?(c[]:=Title,VarSetCapacity(h_history,c.cbData),DllCall("RtlMoveMemory",PTR,&h_history,PTR,c.lpData,PTR,c.cbData),Struct(_AHKVar := "{Int64 ContentsInt64,Double ContentsDouble,PTR object},{char *mByteContents,LPTSTR CharContents},{UINT_PTR Length,_AHKVar *AliasFor},{UINT_PTR Capacity,UINT_PTR BIV},BYTE HowAllocated,BYTE Attrib,BYTE IsLocal,BYTE Type,LPTSTR Name",getvar(h_history),{Attrib:1,Length:c.cbData}),h_history:=ObjLoad(&h_history), h_history.A_Args?A_Args:=h_history.A_Args:0)
:(c.lpData:=fox.GetAddress(Script),c.cbData:=fox.GetCapacity(Script),SendMessage_(StrGet(NumGet(Title + 2*A_PtrSize)),0x4a,1,c[]),OnMessage(0x4a,A_ScriptHwnd,"AhkRun",0),fox.Delete(Script)),0
Thread:=IsObject(Script)?Script:{Script:Script},Args?Thread.A_Args:=IsObject(Args)?Args:[Args]:""
,IsObject(Script)?Thread.Reload?Thread.Reload++:Thread.Reload:=1:"",Thread.Tick:=A_TickCount
if (-1=p1:=DllCall("CreateNamedPipe","str",Pipe:="\\.\pipe\" (Title=""?Thread.name?Thread.name:"AHK - ":Thread.name:=Title) "(" A_TickCount ")","uint",2,"uint",0,"uint",255,"uint",0,"uint",0,"Ptr",0,"Ptr",0))
or (-1=p2:=DllCall("CreateNamedPipe","str",Pipe,"uint",2,"uint",0,"uint",255,"uint",0,"uint",0,"Ptr",0,"Ptr",0))
Return 0
Run, % (Path?Path:A_AhkPath) " `"" Pipe "`"" ,,UseErrorLevel HIDE,P
If ErrorLevel
return DllCall("CloseHandle","Ptr",p1),DllCall("CloseHandle","Ptr",p2),0
Script:=chr(0xfeff) "#Include <ScriptStruct>`nGlobal h_Caller,h_CallerPid,h_CallerId,h_CallerHwnd,h_history`nAhkRun__Global(w:=`"`",l:=`"`"){`nstatic A__ScriptDir := `"" A_ScriptDir "`",r:=AhkRun__Global()`n"
. (Tray?"":"#NoTrayIcon") "`nSetWorkingDir," A_WorkingDir "`nScriptStruct().mFileDir[`"`"] := &A__ScriptDir"
. "`nh_Caller:=`"" A_ScriptName "`",h_CallerPid:=" (Thread.Reload?h_CallerPid:ProcessExist()) ",h_CallerHwnd:=" A_ScriptHwnd ",h_CallerId:=`"" h_id "`""
. ",VarSetCapacity(Struct, 3*A_PtrSize, 0),NumPut((StrLen(Hwnd:=A_ScriptHwnd) + 1) * 2, Struct, A_PtrSize),NumPut(&Hwnd, Struct, 2*A_PtrSize),onmessage(0x4a,A_ScriptHwnd,`"AhkRun`",-1)"
. ",SendMessage_(" A_ScriptHwnd ",0x4a," P ",&Struct)`nonmessage(0x4a,A_ScriptHwnd,`"AhkRun`",0)`n}`nReload(){`nAhkRun(h_history)`nExitApp`n}`n" Thread.Script
,len:=ObjDump(Thread,data2)
,DllCall("ConnectNamedPipe","Ptr",p1,"Ptr",0),DllCall("CloseHandle","Ptr",p1),DllCall("ConnectNamedPipe","Ptr",p2,"Ptr",0)
if s:=DllCall("WriteFile","Ptr",p2,"Wstr",Script,"UInt",StrLen(Script)*2+4,"uint*",0,"Ptr",0)
{
fox.SetCapacity(P,len),RtlMoveMemory(fox.GetAddress(P),&data2,len)
,OnMessage(0x4a,A_ScriptHwnd,"AhkRun",-1),DllCall("CloseHandle","Ptr",p2),t:=A_TickCount
Sleep, 30
while fox.HasKey(P) and ((A_TickCount-t)<10000)
Sleep, -1
if fox.HasKey(P)
OnMessage(0x4a,A_ScriptHwnd,"AhkRun",0),fox.Delete(P)
}
Return s?P:(DllCall("CloseHandle","Ptr",p2),0)
}
记略:
Pipe的管道名称会触发#Singleinstance的作用机制,即使使用了#Singleinstance OFF, 存在重名时加载新进程也会多使用一倍的时间.
所以直接在名字后面加上 A_TickCount 变量,以杜绝重名.
使用了大量H2的内置函数,故代码较简单. 大部分代码来自 HotKeyIt.