; @jugador #include-once ; #FUNCTION# ============================================================================= ; Name ..........: __AutoItThread_Bootstrapper ; ======================================================================================== Func __AutoItThread_Bootstrapper() If $CmdLine[0] >= 2 And $CmdLine[1] == "--run-thread-worker" Then Local $sFunc = $CmdLine[2] Local $vResult = "" If $CmdLine[0] >= 3 Then Local $aRawParams = StringSplit($CmdLine[3], "|", 2) Local $iParamCount = UBound($aRawParams) Local $aCallArgs[$iParamCount + 1] $aCallArgs[0] = "CallArgArray" For $i = 0 To $iParamCount - 1 $aCallArgs[$i + 1] = $aRawParams[$i] Next $vResult = Call($sFunc, $aCallArgs) Else $vResult = Call($sFunc) EndIf If $vResult <> "" Then __Thread_WriteRawStdout(String($vResult)) Exit EndIf Return False EndFunc ; #FUNCTION# ============================================================================= ; Name ..........: __AutoItCreateThread ; ======================================================================================== Func __AutoItCreateThread($sTargetFunction, $vParams = "") Local $sParamString = "" If IsArray($vParams) Then For $i = 0 To UBound($vParams) - 1 $sParamString &= $vParams[$i] & "|" Next $sParamString = StringTrimRight($sParamString, 1) ElseIf $vParams <> "" Then $sParamString = $vParams EndIf Local $sPayload = '--run-thread-worker "' & $sTargetFunction & '"' If $sParamString <> "" Then $sPayload &= ' "' & $sParamString & '"' Local $sCommand = '"' & @AutoItExe & '" /AutoIt3ExecuteScript "' & @ScriptFullPath & '" ' & $sPayload Local $tSecAttr = DllStructCreate("dword Length;ptr Descriptor;bool InheritHandle") DllStructSetData($tSecAttr, "Length", DllStructGetSize($tSecAttr)) DllStructSetData($tSecAttr, "InheritHandle", True) Local $hReadPipe, $hWritePipe Local $aPipe = DllCall("kernel32.dll", "bool", "CreatePipe", _ "handle*", 0, "handle*", 0, "ptr", DllStructGetPtr($tSecAttr), "dword", 0) If @error Or Not $aPipe[0] Then Return SetError(1, 0, 0) $hReadPipe = $aPipe[1] $hWritePipe = $aPipe[2] DllCall("kernel32.dll", "bool", "SetHandleInformation", "handle", $hReadPipe, "dword", 1, "dword", 0) Local $tStartupInfo = DllStructCreate("dword cb;ptr Reserved;ptr Desktop;ptr Title;dword X;dword Y;dword XSize;dword YSize;dword XCountChars;dword YCountChars;" & _ "dword FillAttribute;dword Flags;word ShowWindow;word Reserved2;ptr Reserved3;handle StdInput;handle StdOutput;handle StdError") DllStructSetData($tStartupInfo, "cb", DllStructGetSize($tStartupInfo)) DllStructSetData($tStartupInfo, "Flags", 0x00000100) DllStructSetData($tStartupInfo, "StdOutput", $hWritePipe) DllStructSetData($tStartupInfo, "StdError", $hWritePipe) Local $tProcessInfo = DllStructCreate("handle Process;handle Thread;dword ProcessId;dword ThreadId") Local $aCreate = DllCall("kernel32.dll", "bool", "CreateProcessW", "ptr", 0, "wstr", $sCommand, "ptr", 0, "ptr", 0, "bool", True, _ "dword", 0x00000008, "ptr", 0, "ptr", 0, "ptr", DllStructGetPtr($tStartupInfo), "ptr", DllStructGetPtr($tProcessInfo)) DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hWritePipe) If @error Or Not $aCreate[0] Then DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hReadPipe) Return SetError(2, 0, 0) EndIf DllCall("kernel32.dll", "CloseHandle", "handle", DllStructGetData($tProcessInfo, "Thread")) Local $aThreadData[2] = [DllStructGetData($tProcessInfo, "Process"), $hReadPipe] Return $aThreadData EndFunc ; #FUNCTION# ============================================================================= ; Name ..........: __AutoItWaitThread ; ======================================================================================== Func __AutoItWaitThread($aThreadData) If Not IsArray($aThreadData) Then Return "" Local $hProcess = $aThreadData[0] Local $hReadPipe = $aThreadData[1] DllCall("kernel32.dll", "dword", "WaitForSingleObject", "handle", $hProcess, "dword", -1) DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hProcess) Local $aPeek = DllCall("kernel32.dll", "bool", "PeekNamedPipe", "handle", $hReadPipe, "ptr", 0, "dword", 0, "ptr", 0, "dword*", 0, "dword*", 0) Local $iTotalBytesAvail = $aPeek[5] Local $sResult = "" If $iTotalBytesAvail > 0 Then If Mod($iTotalBytesAvail, 2) <> 0 Then $iTotalBytesAvail += 1 Local $iCharCount = Int($iTotalBytesAvail / 2) Local $tBuffer = DllStructCreate("wchar[" & $iCharCount & "]") Local $aReadResult = DllCall("kernel32.dll", "bool", "ReadFile", "handle", $hReadPipe, "ptr", DllStructGetPtr($tBuffer), "dword", $iTotalBytesAvail, "dword*", 0, "ptr", 0) If Not @error And $aReadResult[0] Then $sResult = DllStructGetData($tBuffer, 1) EndIf EndIf DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hReadPipe) Return $sResult EndFunc ; #FUNCTION# ============================================================================= ; Name ..........: __WM_COPYDATA_SendData ; ======================================================================================== Func __WM_COPYDATA_SendData($hTargetWindow, $sData) Local $hWnd = HWnd($hTargetWindow) If Not IsHWnd($hWnd) Then Return False Local $iLen = StringLen($sData) + 1 Local $tString = DllStructCreate("wchar[" & $iLen & "]") DllStructSetData($tString, 1, $sData) Local Const $iWM_COPYDATA = 0x004A Local $tCOPYDATASTRUCT = DllStructCreate("ulong_ptr dwData;dword cbData;ptr lpData") DllStructSetData($tCOPYDATASTRUCT, "dwData", @AutoItPID) DllStructSetData($tCOPYDATASTRUCT, "cbData", $iLen * 2) DllStructSetData($tCOPYDATASTRUCT, "lpData", DllStructGetPtr($tString)) DllCall("user32.dll", "lresult", "SendMessageW", "hwnd", $hWnd, "uint", $iWM_COPYDATA, "wparam", 0, "lparam", DllStructGetPtr($tCOPYDATASTRUCT)) Return True EndFunc ; Internal Helper: ; #FUNCTION# ============================================================================= ; Name ..........: __Thread_WriteRawStdout ; ======================================================================================== Func __Thread_WriteRawStdout($sText) Local $hStdout = DllCall("kernel32.dll", "handle", "GetStdHandle", "dword", -11)[0] If $hStdout = 0 Or $hStdout = -1 Then Return Local $iCharCount = StringLen($sText) Local $iByteCount = $iCharCount * 2 Local $tBuffer = DllStructCreate("wchar[" & ($iCharCount + 1) & "]") DllStructSetData($tBuffer, 1, $sText) Local $dWritten = 0 DllCall("kernel32.dll", "bool", "WriteFile", _ "handle", $hStdout, "ptr", DllStructGetPtr($tBuffer), "dword", $iByteCount, "dword*", $dWritten, "ptr", 0) EndFunc