wolf9228 Posted March 22, 2020 Share Posted March 22, 2020 (edited) This library allows the creation of several Child processes from the parent process, and communication between the parent and Child processes can be done by calling function smoothly, quickly and efficiently ... Thank you. Thred create function does not work in autoit language if the process name can be hidden from task manager This example will be a solution to the Thred problem ... Thank you. Child_Process_Library Child_Process_Library.zip Child_Process_Library Child_Process_Library.zip Another example DownloaderMultiFiles.zip ;------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ DownloaderMultiFiles.au3 expandcollapse popup#include "Child_Process_Library_Constants.au3" If $CmdLine[0] = 0 Or Not ($CmdLine[1] == "NewChProcess") Then ParentWinMain() Else StartWinMain() EndIf Func ParentWinMain() DownloadExample() EndFunc Func ChildWinMain() Return True ; False Exit /// True Continue EndFunc Func DownloadExample() $controlID1 = DownloaderMultiFiles($Array,"https://download.microsoft.com/download/4/7/A/47A0F7B9-1F0F-41B0-AA42-00FD16337268/Windows6.1-KB947821-v34-x86.msu",@ScriptDir & "\Dir1\v34-x86.msu") GUICtrlSetOnEventEx($controlID1,$BN_CLICKED,"Clicked_Pause_Buttons") GUICtrlSetOnEventEx($controlID1 + 1,$BN_CLICKED,"Clicked_Cancel_Buttons") $controlID2 = DownloaderMultiFiles($Array,"http://download.winzip.com/winzip150.exe",@ScriptDir & "\Dir1\winzip150.exe") GUICtrlSetOnEventEx($controlID2,$BN_CLICKED,"Clicked_Pause_Buttons") GUICtrlSetOnEventEx($controlID2 + 1,$BN_CLICKED,"Clicked_Cancel_Buttons") $controlID3 = DownloaderMultiFiles($Array,"http://www.flash-swf-converter.com/downloads/swfconverter.exe"," ",2) GUICtrlSetOnEventEx($controlID3,$BN_CLICKED,"Clicked_Pause_Buttons") GUICtrlSetOnEventEx($controlID3 + 1,$BN_CLICKED,"Clicked_Cancel_Buttons") $controlID4 = DownloaderMultiFiles($Array,"https://www.win-rar.com/fileadmin/winrar-versions/winrar/wrar580.exe",@ScriptDir & "\Dir2\wrar580.exe") GUICtrlSetOnEventEx($controlID4,$BN_CLICKED,"Clicked_Pause_Buttons") GUICtrlSetOnEventEx($controlID4 + 1,$BN_CLICKED,"Clicked_Cancel_Buttons") While 1 if ($complete = 1) Then $complete = ProgressLoop($Array) Else MsgBox(0,"","download is complete") GUIDelete($Array[0][0]) Exit EndIf WEnd EndFunc Func Clicked_Pause_Buttons($ControlID,$NotificationCode) $WPARAM = OnEventExGetWParam($ControlID,$NotificationCode) $LPARAM = OnEventExGetLParam($ControlID,$NotificationCode) $HWND = OnEventExGetHWND($ControlID,$NotificationCode) For $i = 0 To UBound($Array) - 1 if $ControlID = $Array[$i][5] Then ExitLoop Next $Array[$i][9] = Not $Array[$i][9] if ($Array[$i][9]) Then GUICtrlSetData($ControlID,"Reset") Else GUICtrlSetData($ControlID,"Pause") EndIf $ProNumber = EnvGet($ControlID) PauseDownload($ProNumber,$Array[$i][9]) EndFunc Func Clicked_Cancel_Buttons($ControlID,$NotificationCode) $WPARAM = OnEventExGetWParam($ControlID,$NotificationCode) $LPARAM = OnEventExGetLParam($ControlID,$NotificationCode) $HWND = OnEventExGetHWND($ControlID,$NotificationCode) $ProNumber = EnvGet($ControlID) CancelDownload($ProNumber) EndFunc Func ProgressLoop($Array) Dim $TempArray[1][10] $complete = 2 For $i = 0 To UBound($Array) - 1 $ProgressTime = $Array[$i][8] Sleep($ProgressTime) $InfoArray = DownloadGetInfo($Array[$i][7]) if Not @error Then if ($InfoArray[2]) Then _ $TotalReadTimes = $InfoArray[1] $NumberOfBytesRead = $InfoArray[2] $FileSize = $InfoArray[3] $IsComplete = $InfoArray[4] $PNum = StringLeft(((100 / $FileSize) * $NumberOfBytesRead),5) GUICtrlSetData($Array[$i][3],$PNum) GUICtrlSetData($Array[$i][4],"[" & $PNum & " % ] ( " & StringLeft(int($NumberOfBytesRead / 1024) / 1024 ,6) _ & " OF " & StringLeft(int($FileSize /1024) / 1024 ,6) & " ) MB") If Not ($IsComplete) Then $complete = 1 $TempArray[UBound($TempArray) -1][0] = $Array[$i][0] $TempArray[UBound($TempArray) -1][1] = $Array[$i][1] $TempArray[UBound($TempArray) -1][2] = $Array[$i][2] $TempArray[UBound($TempArray) -1][3] = $Array[$i][3] $TempArray[UBound($TempArray) -1][4] = $Array[$i][4] $TempArray[UBound($TempArray) -1][5] = $Array[$i][5] $TempArray[UBound($TempArray) -1][6] = $Array[$i][6] $TempArray[UBound($TempArray) -1][7] = $Array[$i][7] $TempArray[UBound($TempArray) -1][8] = $Array[$i][8] $TempArray[UBound($TempArray) -1][9] = $Array[$i][9] ReDim $TempArray[UBound($TempArray) + 1][10] Else GUICtrlSetBkColor($Array[$i][4] - 2, $GUI_BKCOLOR_TRANSPARENT) GUICtrlSetBkColor($Array[$i][4], $GUI_BKCOLOR_TRANSPARENT) EndIf EndIf Next if $complete = 2 Then Else ReDim $TempArray[UBound($TempArray) - 1][10] $Array = $TempArray EndIf Return $complete EndFunc Func DownloaderMultiFiles(ByRef $Array,$link,$FileName,$iFlag = 1,$ProgressTime = 100) if Not IsArray($Array) Then Dim $Array[1][10] $Array[0][0] = GUICreate("Downloader Progress", 785, 140, 5, 200, _ BitOR($WS_MINIMIZEBOX,$WS_SYSMENU,$WS_CAPTION,$WS_POPUP,$WS_POPUPWINDOW _ ,$WS_GROUP,$WS_BORDER,$WS_CLIPSIBLINGS)) GUISetState(@SW_SHOW) Else ReDim $Array[UBound($Array) + 1][10] EndIf If $iFlag = 1 Then $OutDir = StringSplit($FileName,"\") if Not FileExists(StringTrimRight($FileName,StringLen($OutDir[$OutDir[0]]))) _ Then DirCreate(StringTrimRight($FileName,StringLen($OutDir[$OutDir[0]]))) $Array[UBound($Array) - 1][1] = $link $Array[UBound($Array) - 1][2] = $FileName GUICtrlCreateLabel(StringLeft($OutDir[$OutDir[0]],23), 10, 10 + ((UBound($Array) - 1) * 30), 170, 20, BitOR($SS_CENTER,$WS_BORDER)) Else $Array[UBound($Array) - 1][1] = $link GUICtrlCreateLabel("< [ Memory ] >", 10, 10 + ((UBound($Array) - 1) * 30), 170, 20, BitOR($SS_CENTER,$WS_BORDER)) EndIf GUICtrlSetFont(-1, 10, 600, 0, "") GUICtrlSetBkColor(-1, 0xFFFFFF) $Array[UBound($Array) - 1][3] = GUICtrlCreateProgress(190, 10 + ((UBound($Array) - 1) * 30), 200, 20) $Array[UBound($Array) - 1][4] = GUICtrlCreateLabel("", 400, 10 + ((UBound($Array) - 1) * 30), 250, 20,BitOR($SS_CENTER,$WS_BORDER)) GUICtrlSetFont(-1, 10, 600, 0, "") GUICtrlSetBkColor(-1, 0xFFFFFF) $Array[UBound($Array) - 1][5] = GUICtrlCreateButton("Pause", 655, 10 + ((UBound($Array) - 1) * 30), 60,20) GUICtrlSetFont(-1, 10, 600, 0, "") $Array[UBound($Array) - 1][6] = GUICtrlCreateButton("Cancel", 720, 10 + ((UBound($Array) - 1) * 30), 60,20) GUICtrlSetFont(-1, 10, 600, 0, "") $Array[UBound($Array) - 1][7] = DownloadFile($Array[UBound($Array) - 1][1],$Array[UBound($Array) - 1][2],128,$iFlag) EnvSet($Array[UBound($Array) - 1][5],$Array[UBound($Array) - 1][7]) EnvSet($Array[UBound($Array) - 1][6],$Array[UBound($Array) - 1][7]) $Array[UBound($Array) - 1][8] = $ProgressTime Return $Array[UBound($Array) - 1][5] EndFunc Func DownloadFile($Url,$FilePath,$BytesNumberAtaTime = 1,$iFlag = 1) $ProcNumA = NewChProcess() $Url = PtrToCallPtr($Url) $FilePath = PtrToCallPtr($FilePath) $ArrayInfoPtr[$ProcNumA - 1] = CallChProcess($ProcNumA,"GetDownloadInfoPtr",0) ReDim $ArrayInfoPtr[$ProcNumA + 1] $Return = CallChProcess($ProcNumA,"Inet_Read",1,$Url,$FilePath,$BytesNumberAtaTime,$iFlag) Return $ProcNumA EndFunc Func DownloadGetInfo($ProNumber) $Prohandle = Prohandle_From_ProNum($ProNumber) $BOOL = cRead_Ptr($Prohandle,$ArrayInfoPtr[$ProNumber - 1],$Down_InfoPtr,$Down_InfoSize) if Not $BOOL Then Return SetError(1,0,$InfoArray) $InfoArray[0] = DllStructGetData($Down_Info,1) $InfoArray[1] = DllStructGetData($Down_Info,2) $InfoArray[2] = DllStructGetData($Down_Info,3) $InfoArray[3] = DllStructGetData($Down_Info,4) $InfoArray[4] = DllStructGetData($Down_Info,5) $InfoArray[5] = DllStructGetData($Down_Info,6) $InfoArray[6] = DllStructGetData($Down_Info,7) $InfoArray[7] = DllStructGetData($Down_Info,8) Return SetError(0,0,$InfoArray) EndFunc Func PauseDownload($ProNumber,$BoolPause = 1) DllStructSetData($CaPaStru,1,$BoolPause) $MovP = ($Down_InfoSize - $CaPaStruSize) $Prohandle = Prohandle_From_ProNum($ProNumber) cWrite_Ptr($Prohandle,$ArrayInfoPtr[$ProNumber - 1] + $MovP,$CaPaStruPtr,$CaPaStruSize) EndFunc Func CancelDownload($ProNumber) DllStructSetData($CaPaStru,1,1) $MovP = ($Down_InfoSize - ($CaPaStruSize * 2)) $Prohandle = Prohandle_From_ProNum($ProNumber) cWrite_Ptr($Prohandle,$ArrayInfoPtr[$ProNumber - 1] + $MovP,$CaPaStruPtr,$CaPaStruSize) EndFunc Func Inet_Read($lpszUrl,$FileName,$ByteAtaTime,$Flag = 0) Local $IsComplete = False,$hFile $lpszUrl = CallPtrToPtr($lpszUrl,$ParentProhandle) $FileName = CallPtrToPtr($FileName,$ParentProhandle) if ($ByteAtaTime <= 0) Then DllStructSetData($Down_Info,6,1) ; Error Return ReturnToReturnCall(False) EndIf $HIntOpen = InternetOpen("OPEN") if Not ($HIntOpen) Then DllStructSetData($Down_Info,6,2) ; Error Return ReturnToReturnCall(False) EndIf $HIntOpenUrl = InternetOpenUrl($HIntOpen,$lpszUrl,"",0,0,0) if Not ($HIntOpenUrl) Then InternetCloseHandle($HIntOpen) DllStructSetData($Down_Info,6,3) ; Error Return ReturnToReturnCall(False) EndIf $FileSize = HttpQueryInfo($HIntOpenUrl,5) ; HTTP_QUERY_CONTENT_LENGTH = 5 if @error Then InternetCloseHandle($HIntOpen) InternetCloseHandle($HIntOpenUrl) DllStructSetData($Down_Info,6,4) ; Error Return ReturnToReturnCall(False) EndIf $FileSize = Abs(Number($FileSize)) DllStructSetData($Down_Info,4,$FileSize) if $Flag = 1 Then $hFile = _WinAPI_CreateFile($FileName,1) if Not $hFile Then InternetCloseHandle($HIntOpen) InternetCloseHandle($HIntOpenUrl) DllStructSetData($Down_Info,6,6) ; Error Return ReturnToReturnCall(False) EndIf EndIf Local $BOOL = False,$MovePos = 0,$BytesRead = 0 if $Flag = 1 Then Local $Buffer = DllStructCreate("BYTE Buffer[" & $ByteAtaTime & "]") Local $lpBuffer = DllStructGetPtr($Buffer) While IsParentProcessWork() if ($FileSize - $MovePos) < $ByteAtaTime Then $ByteAtaTime = $FileSize - $MovePos $Cancel = DllStructGetData($Down_Info,7) $Pause = DllStructGetData($Down_Info,8) if $Pause Then ContinueLoop $BOOL = DllCall($jDll,"BOOL","InternetReadFile","HANDLE",$HIntOpenUrl,"ptr",$lpBuffer, _ "DWORD",$ByteAtaTime,"DWORD*",0) $BytesRead = $BOOL[3] $BOOL = $BOOL[0] if $BOOL = False Or $Cancel Then ExitLoop $MovePos += $BytesRead DllStructSetData($Down_Info,3,$MovePos) $BOOL = DllCall($wDll,"BOOL","WriteFile","PTR",$hFile,"PTR",$lpBuffer,"DWORD",$BytesRead,"DWORD*",0,"PTR",0) $BOOL = $BOOL[0] if ($BOOL = False) Or $FileSize = $MovePos Then ExitLoop WEnd Else $MemorySt = DllStructCreate("Byte[" & $FileSize & "]") ; Global $MemoryPtr = DllStructGetPtr($MemorySt) DllStructSetData($Down_Info,$MemoryPtr,1) While IsParentProcessWork() if ($FileSize - $MovePos) < $ByteAtaTime Then $ByteAtaTime = $FileSize - $MovePos $Cancel = DllStructGetData($Down_Info,7) $Pause = DllStructGetData($Down_Info,8) if $Pause Then ContinueLoop $BOOL = DllCall($jDll,"BOOL","InternetReadFile","HANDLE",$HIntOpenUrl,"ptr",$MemoryPtr + $MovePos, _ "DWORD",$ByteAtaTime,"DWORD*",0) $BytesRead = $BOOL[3] $BOOL = $BOOL[0] if $BOOL = False Or $Cancel Then ExitLoop $MovePos += $BytesRead DllStructSetData($Down_Info,3,$MovePos) if $FileSize = $MovePos Then ExitLoop WEnd EndIf if $Flag = 1 Then _WinAPI_CloseHandle($hFile) if ($BOOL = False) Then InternetCloseHandle($HIntOpen) InternetCloseHandle($HIntOpenUrl) DllStructSetData($Down_Info,6,7) Return ReturnToReturnCall(False) EndIf $IsComplete = True InternetCloseHandle($HIntOpen) InternetCloseHandle($HIntOpenUrl) DllStructSetData($Down_Info,5,$IsComplete) Return ReturnToReturnCall(True) EndFunc Func StartWinMain() $IsChildProcess = True $yCallPtr = Ptr($CmdLine[4]) $ParentProcessID = Int($CmdLine[3]) $yProcessNumber = Int($CmdLine[2]) $ParentProhandle = GetPro_handle(0,$ParentProcessID) cRead_Ptr($ParentProhandle,$yCallPtr,$CallPtr,$CallSize) DllStructSetData($CallStruct,"cFinish",1,$yProcessNumber) DllStructSetData($CallStruct,"CallPtr",$CallPtr,$yProcessNumber) DllStructSetData($CallStruct,"ChProcessID",$ProcessID,$yProcessNumber) cWrite_Ptr($ParentProhandle,$yCallPtr,$CallPtr,$CallSize) While IsParentProcessWork() And ChildWinMain() if DllStructGetData($CallStruct,"TestCall",$yProcessNumber) Then CallFunc() WEnd Exit EndFunc Func IsParentProcessWork($pTime = 5000) if (TimerDiff($pbeginA) < $pTime) Then Return True if Not ProcessExists($ParentProcessID) Then Return False $pbeginA = TimerInit() Return True EndFunc Func NewChProcess($WaitChildProcess = True , $Timeout = 5000) ; Calling From Parent Process Only if $IsChildProcess Then Return SetError(1,0,0) ;error 1 if Calling From Child Process if $cMax = $wProcessCount Then Return SetError(2,0,0) ;error 2 Upto Max Of Child dProcess $wProcessCount += 1 DllStructSetData($CallStruct,"cFinish",0,$wProcessCount) $Command = "NewChProcess " & $wProcessCount & " " & $ProcessID & " " & $CallPtr if (@Compiled) Then $ChProcessID = Run(FileGetShortName(@AutoItExe) & " " & $Command) Else $ChProcessID = Run(FileGetShortName(@AutoItExe) & " " & FileGetShortName(@ScriptFullPath) & " " & $Command) EndIf if $WaitChildProcess Then $begin = TimerInit() While Not DllStructGetData($CallStruct,"cFinish",$wProcessCount) And _ ProcessExists($ChProcessID) And TimerDiff($begin) <= $Timeout Sleep(100) WEnd EndIf $Prohandle = GetPro_handle(0,$ChProcessID) if @error Then Return SetError(3,0,0) ; error 3 error In Get Child Process handle DllStructSetData($CallStruct,"ChProcesshandle",$Prohandle,$wProcessCount) ; Return New Child Process Number Return $wProcessCount EndFunc Func CallChProcess($ProcessNum,$FNam,$RtIly,$Pam1 = 0,$Pam2 = 0,$Pam3 = 0 _ , $Pam4 = 0 , $Pam5 = 0 ,$Pam6 = 0,$Pam7 = 0,$Pam8 = 0,$Pam9 = 0,$Pam10 = 0) Local $NumParams = @NumParams - 3 DllStructSetData($CallStruct,"ParamCount",$NumParams) Switch $NumParams Case 1 DllStructSetData($CallStruct,2,$Pam1) Case 2 DllStructSetData($CallStruct,2,$Pam1) DllStructSetData($CallStruct,3,$Pam2) Case 3 DllStructSetData($CallStruct,2,$Pam1) DllStructSetData($CallStruct,3,$Pam2) DllStructSetData($CallStruct,4,$Pam3) Case 4 DllStructSetData($CallStruct,2,$Pam1) DllStructSetData($CallStruct,3,$Pam2) DllStructSetData($CallStruct,4,$Pam3) DllStructSetData($CallStruct,5,$Pam4) Case 5 DllStructSetData($CallStruct,2,$Pam1) DllStructSetData($CallStruct,3,$Pam2) DllStructSetData($CallStruct,4,$Pam3) DllStructSetData($CallStruct,5,$Pam4) DllStructSetData($CallStruct,6,$Pam5) Case 6 DllStructSetData($CallStruct,2,$Pam1) DllStructSetData($CallStruct,3,$Pam2) DllStructSetData($CallStruct,4,$Pam3) DllStructSetData($CallStruct,5,$Pam4) DllStructSetData($CallStruct,6,$Pam5) DllStructSetData($CallStruct,7,$Pam6) Case 7 DllStructSetData($CallStruct,2,$Pam1) DllStructSetData($CallStruct,3,$Pam2) DllStructSetData($CallStruct,4,$Pam3) DllStructSetData($CallStruct,5,$Pam4) DllStructSetData($CallStruct,6,$Pam5) DllStructSetData($CallStruct,7,$Pam6) DllStructSetData($CallStruct,8,$Pam7) Case 8 DllStructSetData($CallStruct,2,$Pam1) DllStructSetData($CallStruct,3,$Pam2) DllStructSetData($CallStruct,4,$Pam3) DllStructSetData($CallStruct,5,$Pam4) DllStructSetData($CallStruct,6,$Pam5) DllStructSetData($CallStruct,7,$Pam6) DllStructSetData($CallStruct,8,$Pam7) DllStructSetData($CallStruct,9,$Pam8) Case 9 DllStructSetData($CallStruct,2, $Pam1) DllStructSetData($CallStruct,3, $Pam2) DllStructSetData($CallStruct,4, $Pam3) DllStructSetData($CallStruct,5, $Pam4) DllStructSetData($CallStruct,6, $Pam5) DllStructSetData($CallStruct,7, $Pam6) DllStructSetData($CallStruct,8, $Pam7) DllStructSetData($CallStruct,9, $Pam8) DllStructSetData($CallStruct,10,$Pam9) Case 10 DllStructSetData($CallStruct,2, $Pam1) DllStructSetData($CallStruct,3, $Pam2) DllStructSetData($CallStruct,4, $Pam3) DllStructSetData($CallStruct,5, $Pam4) DllStructSetData($CallStruct,6, $Pam5) DllStructSetData($CallStruct,7, $Pam6) DllStructSetData($CallStruct,8, $Pam7) DllStructSetData($CallStruct,9, $Pam8) DllStructSetData($CallStruct,10,$Pam9) DllStructSetData($CallStruct,11,$Pam10) EndSwitch $yCallPtr = DllStructGetData($CallStruct,"CallPtr",$ProcessNum) $ChProceID = DllStructGetData($CallStruct,"ChProcessID",$ProcessNum) $Prohandle = DllStructGetData($CallStruct,"ChProcesshandle",$ProcessNum) DllStructSetData($CallStruct,"FucName",$FNam) ; Func Name DllStructSetData($CallStruct ,"RtIly",$RtIly) ; Return immediately DllStructSetData($CallStruct,"cFinish",0,$ProcessNum) DllStructSetData($CallStruct,"TestCall",1,$ProcessNum) cWrite_Ptr($Prohandle,$yCallPtr,$CallPtr,$CallSize) Local $BoolA = False , $BoolB = True While ((Not $BoolA) And $BoolB) $BoolA = DllStructGetData($CallStruct,"cFinish",$ProcessNum) $BoolB = ProcessExists($ChProceID) Sleep(100) WEnd if $BoolA Then if $RtIly Then Return SetError(0,0,0) $ReturnPtr = DllStructGetData($CallStruct,"ReturnPtr") Return SetError(0,0,ReturnCallToReturn($ReturnPtr,$Prohandle)) EndIf Return SetError(1,0,0) EndFunc Func CallFunc() $FuncName = DllStructGetData($CallStruct,"FucName") $NumParams = DllStructGetData($CallStruct,"ParamCount") $RtIly = DllStructGetData($CallStruct,"RtIly") ;Return immediately Local $ArgsArray[$NumParams + 1] $ArgsArray[0] = "CallArgArray" Switch $NumParams Case 1 $ArgsArray[1] = DllStructGetData($CallStruct,2) Case 2 $ArgsArray[1] = DllStructGetData($CallStruct,2) $ArgsArray[2] = DllStructGetData($CallStruct,3) Case 3 $ArgsArray[1] = DllStructGetData($CallStruct,2) $ArgsArray[2] = DllStructGetData($CallStruct,3) $ArgsArray[3] = DllStructGetData($CallStruct,4) Case 4 $ArgsArray[1] = DllStructGetData($CallStruct,2) $ArgsArray[2] = DllStructGetData($CallStruct,3) $ArgsArray[3] = DllStructGetData($CallStruct,4) $ArgsArray[4] = DllStructGetData($CallStruct,5) Case 5 $ArgsArray[1] = DllStructGetData($CallStruct,2) $ArgsArray[2] = DllStructGetData($CallStruct,3) $ArgsArray[3] = DllStructGetData($CallStruct,4) $ArgsArray[4] = DllStructGetData($CallStruct,5) $ArgsArray[5] = DllStructGetData($CallStruct,6) Case 6 $ArgsArray[1] = DllStructGetData($CallStruct,2) $ArgsArray[2] = DllStructGetData($CallStruct,3) $ArgsArray[3] = DllStructGetData($CallStruct,4) $ArgsArray[4] = DllStructGetData($CallStruct,5) $ArgsArray[5] = DllStructGetData($CallStruct,6) $ArgsArray[6] = DllStructGetData($CallStruct,7) Case 7 $ArgsArray[1] = DllStructGetData($CallStruct,2) $ArgsArray[2] = DllStructGetData($CallStruct,3) $ArgsArray[3] = DllStructGetData($CallStruct,4) $ArgsArray[4] = DllStructGetData($CallStruct,5) $ArgsArray[5] = DllStructGetData($CallStruct,6) $ArgsArray[6] = DllStructGetData($CallStruct,7) $ArgsArray[7] = DllStructGetData($CallStruct,8) Case 8 $ArgsArray[1] = DllStructGetData($CallStruct,2) $ArgsArray[2] = DllStructGetData($CallStruct,3) $ArgsArray[3] = DllStructGetData($CallStruct,4) $ArgsArray[4] = DllStructGetData($CallStruct,5) $ArgsArray[5] = DllStructGetData($CallStruct,6) $ArgsArray[6] = DllStructGetData($CallStruct,7) $ArgsArray[7] = DllStructGetData($CallStruct,8) $ArgsArray[8] = DllStructGetData($CallStruct,9) Case 9 $ArgsArray[1] = DllStructGetData($CallStruct,2) $ArgsArray[2] = DllStructGetData($CallStruct,3) $ArgsArray[3] = DllStructGetData($CallStruct,4) $ArgsArray[4] = DllStructGetData($CallStruct,5) $ArgsArray[5] = DllStructGetData($CallStruct,6) $ArgsArray[6] = DllStructGetData($CallStruct,7) $ArgsArray[7] = DllStructGetData($CallStruct,8) $ArgsArray[8] = DllStructGetData($CallStruct,9) $ArgsArray[9] =DllStructGetData($CallStruct,10) Case 10 $ArgsArray[1] = DllStructGetData($CallStruct,2) $ArgsArray[2] = DllStructGetData($CallStruct,3) $ArgsArray[3] = DllStructGetData($CallStruct,4) $ArgsArray[4] = DllStructGetData($CallStruct,5) $ArgsArray[5] = DllStructGetData($CallStruct,6) $ArgsArray[6] = DllStructGetData($CallStruct,7) $ArgsArray[7] = DllStructGetData($CallStruct,8) $ArgsArray[8] = DllStructGetData($CallStruct,9) $ArgsArray[9] =DllStructGetData($CallStruct,10) $ArgsArray[10]=DllStructGetData($CallStruct,11) EndSwitch if $RtIly Then DllStructSetData($CallStruct ,"cFinish",1,$yProcessNumber) DllStructSetData($CallStruct,"TestCall",0,$yProcessNumber) cWrite_Ptr($ParentProhandle,$yCallPtr,$CallPtr,$CallSize) EndIf $ReturnPtr = Call($FuncName,$ArgsArray) if Not $RtIly Then DllStructSetData($CallStruct ,"cFinish",1,$yProcessNumber) DllStructSetData($CallStruct,"TestCall",0,$yProcessNumber) DllStructSetData($CallStruct,"ReturnPtr",$ReturnPtr) cWrite_Ptr($ParentProhandle,$yCallPtr,$CallPtr,$CallSize) EndIf EndFunc Func CallPtrToPtr($PtrOrStr,$Prohandle) $Struct = DllStructCreate("Byte Type;Int LenAndSize") $Pointer = DllStructGetPtr($Struct) $Size = DllStructGetSize($Struct) cRead_Ptr($Prohandle,$PtrOrStr,$Pointer,$Size) $LenAndSize = DllStructGetData($Struct,2) Switch DllStructGetData($Struct,1) Case 1 $yTagStruct = "Byte Type;Int Len;WCHAR[" & $LenAndSize & "]" $Struct = DllStructCreate($yTagStruct) $Pointer = DllStructGetPtr($Struct) $Size = DllStructGetSize($Struct) cRead_Ptr($Prohandle,$PtrOrStr,$Pointer,$Size) Return SetError(0,1,DllStructGetData($Struct,3)) Case 2 $yTagStruct = "Byte Type;Int Len;Byte[" & $LenAndSize & "]" $Struct = DllStructCreate($yTagStruct) $Pointer = DllStructGetPtr($Struct) $Size = DllStructGetSize($Struct) cRead_Ptr($Prohandle,$PtrOrStr,$Pointer,$Size) $yStruct = DllStructCreate("byte[" & $LenAndSize & "]") $BPtr = DllStructGetPtr($Struct,3) $YPtr = DllStructGetPtr($yStruct) _MemMoveMemory($BPtr,$YPtr,$LenAndSize) Return SetError(0,2,$yStruct) Case 3 $yTagStruct = "Byte Type;Int Size;Byte[" & $LenAndSize & "];WCHAR TagSt[1000]" $Struct = DllStructCreate($yTagStruct) $Pointer = DllStructGetPtr($Struct) $Size = DllStructGetSize($Struct) cRead_Ptr($Prohandle,$PtrOrStr,$Pointer,$Size) $TagSt = DllStructGetData($Struct,4) $yStruct = DllStructCreate($TagSt) $BPtr = DllStructGetPtr($Struct,3) $YPtr = DllStructGetPtr($yStruct) _MemMoveMemory($BPtr,$YPtr,$LenAndSize) Return SetError(0,3,$yStruct) EndSwitch Return SetError(2,0,0) EndFunc Func PtrToCallPtr($PtrOrStr,$Size = 0,$yTagStruct = -1) Local $Struct Select Case IsString($PtrOrStr) $cLen = StringLen($PtrOrStr) $Struct = DllStructCreate("Byte Type;Int Len;WCHAR[" & $cLen & "]") DllStructSetData($Struct,1,1) DllStructSetData($Struct,2,$cLen) DllStructSetData($Struct,3,$PtrOrStr) Case Else Select Case $yTagStruct == -1 $yTagStruct = "Byte Type;Int Size;Byte[" & $Size & "]" $Struct = DllStructCreate($yTagStruct) DllStructSetData($Struct,1,2) DllStructSetData($Struct,2,$Size) _MemMoveMemory($PtrOrStr,DllStructGetPtr($Struct,3),$Size) Case Else if StringLen($yTagStruct) > 1000 Then Return SetError(1,0,0) if $Size = 0 Then $Size = DllStructGetSize(DllStructCreate($yTagStruct)) $cTagStruct = "Byte Type;Int Size;Byte[" & $Size & "];WCHAR TagSt[1000]" $Struct = DllStructCreate($cTagStruct) DllStructSetData($Struct,1,3) DllStructSetData($Struct,2,$Size) DllStructSetData($Struct,4,$yTagStruct) _MemMoveMemory($PtrOrStr,DllStructGetPtr($Struct,3),$Size) EndSelect EndSelect StructSetGlobal($Struct) ; Read Text In StructSetGlobal Func Return SetError(0,0,DllStructGetPtr($Struct)) EndFunc Func StructSetGlobal($Struct) ; StructSetGlobal ; Set Struct In Global if Struct From Child Process and Read it From Parent Process Or Struct From ;Parent Process and Read it From Child Process ;You can Set 20 Structs before deleting the first Struct /// $GlobalStNum = 20 Switch $GlobalStNum Case $MaxGlobal $GlobalStArray[$GlobalStNum - 1] = $Struct $GlobalStNum = 1 Return $GlobalStNum Case Else $GlobalStArray[$GlobalStNum - 1] = $Struct $GlobalStNum += 1 Return $GlobalStNum EndSwitch EndFunc Func ReturnCallToReturn($ReturnPtr,$Prohandle) $Struct = DllStructCreate("Double") $Pointer = DllStructGetPtr($Struct) $Size = DllStructGetSize($Struct) cRead_Ptr($Prohandle,$ReturnPtr,$Pointer,$Size) Return DllStructGetData($Struct,1) EndFunc Func ReturnToReturnCall($iData) $ReturnSt = DllStructCreate("Double") ; On Global DllStructSetData($ReturnSt,1,$iData) Return DllStructGetPtr($ReturnSt) EndFunc Func Prohandle_From_ProNum($ProNumber = -1) if $ProNumber = -1 Then Return $ParentProhandle Return DllStructGetData($CallStruct,"ChProcesshandle",$ProNumber) EndFunc Func GetPro_handle($eProcessNumber = 0,$iProcessID = -1) if $iProcessID = -1 Then $iProcessID = DllStructGetData($CallStruct,"ChProcessID",$eProcessNumber) $ihProcess = _WinAPI_OpenProcess($iPROCESS_ALL_ACCESS,False,$iProcessID) Return SetError(@error,0,$ihProcess) EndFunc Func cWrite_Ptr($ihProcess,$Address,$Pointer,$Size) Local $iWritten $Return = _WinAPI_WriteProcessMemory($ihProcess,$Address,$Pointer,$Size,$iWritten) Return SetError($Return == False,0,$Return) EndFunc Func cRead_Ptr($ihProcess,$Address,$Pointer,$Size) Local $iRead $Return = _WinAPI_ReadProcessMemory($ihProcess,$Address,$Pointer,$Size,$iRead) Return SetError($Return == False,0,$Return) EndFunc Func CloseProcesshandle($ihProcess) Return _WinAPI_CloseHandle($ihProcess) EndFunc Func GetDownloadInfoPtr() Return ReturnToReturnCall($Down_InfoPtr) EndFunc Func HttpQueryInfo($hRequest,$dwInfoLevel,$lpdwIndex = 0) $lpdwBufferLength = 1000 $DLLSDWORD = DllStructCreate("DWORD") DllStructSetData($DLLSDWORD,1,$lpdwBufferLength) $LPDWORDLENGTH = DllStructGetPtr($DLLSDWORD) $DLLSlpvBuffer = DllStructCreate("WCHAR[" & $lpdwBufferLength & "]") $lpvBuffer = DllStructGetPtr($DLLSlpvBuffer) $BOOL = DllCall($jDll,"BOOL","HttpQueryInfoW","HANDLE",$hRequest,"DWORD",$dwInfoLevel, _ "ptr",$lpvBuffer,"ptr",$LPDWORDLENGTH,"DWORD",$lpdwIndex) if @error Or $BOOL[0] = 0 Then Return SetError(1,0,0) Return SetError(0,0,DllStructGetData($DLLSlpvBuffer,1)) EndFunc Func InternetQueryOption($hInternet,$dwOption) $lpdwBufferLength = 1000 $DLLSDWORD = DllStructCreate("DWORD") DllStructSetData($DLLSDWORD,1,$lpdwBufferLength) $LPDWORDLENGTH = DllStructGetPtr($DLLSDWORD) $DLLSlpvBuffer = DllStructCreate("WCHAR[" & $lpdwBufferLength & "]") $lpvBuffer = DllStructGetPtr($DLLSlpvBuffer) $BOOL = DllCall($jDll,"BOOL","InternetQueryOptionW","HANDLE",$hInternet _ ,"DWORD",$dwOption,"ptr",$lpvBuffer,"ptr",$LPDWORDLENGTH) if @error Or $BOOL[0] = 0 Then Return SetError(1,0,0) Return SetError(0,0,DllStructGetData($DLLSlpvBuffer,1)) EndFunc Func InternetOpenUrl($hInternet,$lpszUrl,$lpszHeaders,$dwHeadersLength,$dwFlags,$dwContext) $HINTERNET = DllCall($jDll,"HANDLE","InternetOpenUrlW","HANDLE",$hInternet,"wstr",$lpszUrl, _ "wstr",$lpszHeaders,"DWORD",$dwHeadersLength,"DWORD",$dwFlags,"ptr",$dwContext) if @error Or Not ($HINTERNET[0]) Then Return SetError(1,0,0) Return SetError(0,0,$HINTERNET[0]) EndFunc Func InternetOpen($lpszAgent,$dwAccessType = 0,$lpszProxyName = "",$lpszProxyBypass = "",$dwFlags = 0) $HINTERNET = DllCall($jDll,"HANDLE","InternetOpenW","wstr",$lpszAgent,"DWORD",$dwAccessType, _ "wstr",$lpszProxyName,"wstr",$lpszProxyBypass,"DWORD",$dwFlags) if @error Or Not ($HINTERNET[0]) Then Return SetError(1,0,0) Return SetError(0,0,$HINTERNET[0]) EndFunc Func InternetCloseHandle($hInternet) $BOOL = DllCall($jDll,"BOOL","InternetCloseHandle","HANDLE",$hInternet) if @error Or $BOOL[0] = 0 Then Return SetError(1,0,0) Return SetError(0,0,$BOOL[0]) EndFunc Child_Process_Library_Constants.au3 expandcollapse popup#include <WinAPI.au3> #include <Memory.au3> #include <GUIConstantsEx.au3> #include <ProgressConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #Include <GuiButton.au3> #Include "GUICtrlSetOnEventEx.au3" Global $MaxGlobal = 20 , $IsChildProcess = 0 , $yCallPtr = 0 , $cMax = 256,$ParentProhandle Global $iSYNCHRONIZE = ( 0x00100000 ) , $iSTANDARD_RIGHTS_REQUIRED = (0x000F0000) Global $iPROCESS_ALL_ACCESS = ( $iSTANDARD_RIGHTS_REQUIRED + $iSYNCHRONIZE + 0xFFF) Global $yProcessNumber = 0 , $GlobalStArray[$MaxGlobal] ,$wProcessCount = 0,$ihProcess = 0 Global $pbeginA = TimerInit() ,$GlobalStNum = 1,$ParentProcessID = 0,$ReturnSt,$MemorySt = 0 ; $yProcessNumber = 0 // Child Process Number In Child Process ; $wProcessCount = 0 // Count Of Child Process In Parent Process ; $ParentProcessID = 0 /// Parent Process ID In Child Process ; $cMax = 256 /// Max Of Child Processs ; $GlobalStArray // Read Text In StructSetGlobal Func ; $MaxGlobal // Read Text In StructSetGlobal Func $tagCallStruct = "int ParamCount;Double aData;Double bData;Double cData;Double dData;Double eData;" & _ "Double fData;Double gData;Double hData;Double iData;Double jData;Ptr ReturnPtr;WCHAR FucName[100];" & _ "int RtIly;int cFinish[" & $cMax & "];int TestCall[" & $cMax & "];Ptr CallPtr[" & $cMax & "];int " & _ "ChProcessID[" & $cMax & "];handle ChProcesshandle["& $cMax & "]" Global $CallStruct = DllStructCreate($tagCallStruct) Global $CallSize = DllStructGetSize($CallStruct) Global $CallPtr = DllStructGetPtr($CallStruct) Global $ProcessID = _WinAPI_GetCurrentProcessID() Global $jDll = DllOpen("Wininet.dll"),$wDll = DllOpen("kernel32.dll") Global $Tag_Download_Info = "HANDLE hMemory;UINT64 TotalReadTimes;UINT64 MovePos;UINT64 FileSize;" & _ "DWORD IsComplete;DWORD IsError;DWORD Cancel;DWORD Pause" , $Array ,$complete = 1 , $Down_Info = _ DllStructCreate($Tag_Download_Info) , $Down_InfoPtr = DllStructGetPtr($Down_Info) , $Down_InfoSize = _ DllStructGetSize($Down_Info) , $ArrayInfoPtr[1] , $InfoArray[8],$CaPaStru = DllStructCreate("DWORD") _ ,$CaPaStruSize = DllStructGetSize($CaPaStru),$CaPaStruPtr = DllStructGetPtr($CaPaStru) GUICtrlSetOnEventEx.au3 expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Global $NotifyStruct = 0 , $TagNotifyStruct = "" ; GUICtrlSetOnEventEx($Control_ID_HWnd,$NotificationCode,$Function) ;$NotificationCode ==> (WM_COMMAND Notification Code And WM_NOTIFY Notification Code) ;$Function ==> ($ControlID,$NotificationCode) ; Return :Note use Func GUICtrlSetOnEventEx($Control_ID_HWnd,$NotificationCode,$Function) $handle = DLLCallbackRegister($Function,"none","int;int") if $handle = 0 Then Return False DllCallbackFree($handle) if IsHWnd($Control_ID_HWnd) Then $hWnd = $Control_ID_HWnd $ControlID = DllCall("user32.dll", "int", "GetDlgCtrlID", "hwnd", $hWnd) If @error Then Return False $ControlID = $ControlID[0] if Not ($ControlID) Then Return False Else $ControlID = $Control_ID_HWnd $hWnd = GUICtrlGetHandle($ControlID) if Not IsHWnd($hWnd) Then Return False EndIf $iNotificationCode = $NotificationCode if StringInStr($NotificationCode,"-") Then _ $iNotificationCode = StringReplace($NotificationCode,"-","A") if Not IsDllStruct($NotifyStruct) Then Local $count = 1 $Len = StringLen($Function) $TagNotifyStruct = _ "int count;WPARAM WPARAM;LPARAM LPARAM;int Test;int " & String($hWnd & $iNotificationCode) & _ ";HWND HWND" & String($count) & ";int ControlID" & String($count) & ";int NotificationCode" & _ String($count) & ";char Function" & String($count) & "[" & String($Len) & "]" $NotifyStruct = DllStructCreate($TagNotifyStruct) DllStructSetData($NotifyStruct,"count",$count) DllStructSetData($NotifyStruct,String($hWnd & $iNotificationCode),$count) DllStructSetData($NotifyStruct,"HWND" & String($count),$hWnd) DllStructSetData($NotifyStruct,"ControlID" & String($count),$ControlID) DllStructSetData($NotifyStruct,"NotificationCode" & String($count),$NotificationCode) DllStructSetData($NotifyStruct,"Function" & String($count),$Function) Else $count = DllStructGetData($NotifyStruct,String($hWnd & $iNotificationCode)) if ($count) Then Return False Local $count = DllStructGetData($NotifyStruct,"count") + 1 $Len = StringLen($Function) $TagNotifyStruct &= _ ";int " & String($hWnd & $iNotificationCode) & ";HWND HWND" & String($count) & _ ";int NotificationCode" & String($count) & ";int ControlID" & String($count) & _ ";char Function" & String($count) & "[" & String($Len) & "]" $iLength = DllStructGetSize($NotifyStruct) $iNotifyStruct = DllStructCreate($TagNotifyStruct) DllCall("kernel32.dll","none","RtlMoveMemory","ptr",DllStructGetPtr($iNotifyStruct) _ ,"ptr",DllStructGetPtr($NotifyStruct),"ulong_ptr",$iLength) $NotifyStruct = $iNotifyStruct DllStructSetData($NotifyStruct,"count",$count) DllStructSetData($NotifyStruct,String($hWnd & $iNotificationCode),$count) DllStructSetData($NotifyStruct,"HWND" & String($count),$hWnd) DllStructSetData($NotifyStruct,"ControlID" & String($count),$ControlID) DllStructSetData($NotifyStruct,"NotificationCode" & String($count),$NotificationCode) DllStructSetData($NotifyStruct,"Function" & String($count),$Function) EndIf GUIRegisterMsg($WM_NOTIFY,"OnEventExProc") GUIRegisterMsg($WM_COMMAND,"OnEventExProc") Return True EndFunc Func OnEventExProc($hWnd,$Msg,$wParam,$lParam) Select Case $Msg = $WM_NOTIFY Local $OnEventExtagNMHDR = "hwnd hWndFrom;uint_ptr IDFrom;INT Code" $tNMHDR = DllStructCreate($OnEventExtagNMHDR, $lParam) $MsgHwnd = DllStructGetData($tNMHDR, "hWndFrom") $MsgCode = DllStructGetData($tNMHDR, "Code") Case $Msg = $WM_COMMAND $MsgHwnd = $lParam $MsgCode = BitShift($wParam, 16) EndSelect $iMsgCode = $MsgCode if StringInStr($MsgCode,"-") Then _ $iMsgCode = StringReplace($MsgCode,"-","A") $count = DllStructGetData($NotifyStruct,String($MsgHwnd & $iMsgCode)) if Not ($count) Then Return $GUI_RUNDEFMSG DllStructSetData($NotifyStruct,"WPARAM",$wParam) DllStructSetData($NotifyStruct,"LPARAM",$lParam) $OnEvHWND = DllStructGetData($NotifyStruct,"HWND" & String($count)) $ControlID = DllStructGetData($NotifyStruct,"ControlID" & String($count)) $OnEvNotificationCode = DllStructGetData($NotifyStruct,"NotificationCode" & String($count)) $OnEvFunction = DllStructGetData($NotifyStruct,"Function" & String($count)) DllStructSetData($NotifyStruct,"Test",1) if ($MsgHwnd = $OnEvHWND And $MsgCode = $OnEvNotificationCode) Then _ Call($OnEvFunction,$ControlID,$OnEvNotificationCode) DllStructSetData($NotifyStruct,"Test",0) Return $GUI_RUNDEFMSG EndFunc Func OnEventExGetWParam($ControlID,$NotificationCode) $Test = DllStructGetData($NotifyStruct,"Test") if Not ($Test) Then Return False $hWnd = GUICtrlGetHandle($ControlID) if Not IsHWnd($hWnd) Then Return False $iNotificationCode = $NotificationCode if StringInStr($NotificationCode,"-") Then _ $iNotificationCode = StringReplace($NotificationCode,"-","A") $count = DllStructGetData($NotifyStruct,String($hWnd & $iNotificationCode)) if Not ($count) Then Return False Return DllStructGetData($NotifyStruct,"WPARAM") EndFunc Func OnEventExGetLParam($ControlID,$NotificationCode) $Test = DllStructGetData($NotifyStruct,"Test") if Not ($Test) Then Return False $hWnd = GUICtrlGetHandle($ControlID) if Not IsHWnd($hWnd) Then Return False $iNotificationCode = $NotificationCode if StringInStr($NotificationCode,"-") Then _ $iNotificationCode = StringReplace($NotificationCode,"-","A") $count = DllStructGetData($NotifyStruct,String($hWnd & $iNotificationCode)) if Not ($count) Then Return False Return DllStructGetData($NotifyStruct,"LPARAM") EndFunc Func OnEventExGetHWND($ControlID,$NotificationCode) $Test = DllStructGetData($NotifyStruct,"Test") if Not ($Test) Then Return False $hWnd = GUICtrlGetHandle($ControlID) if Not IsHWnd($hWnd) Then Return False $iNotificationCode = $NotificationCode if StringInStr($NotificationCode,"-") Then _ $iNotificationCode = StringReplace($NotificationCode,"-","A") $count = DllStructGetData($NotifyStruct,String($hWnd & $iNotificationCode)) if Not ($count) Then Return False Return DllStructGetData($NotifyStruct,"HWND" & String($count)) EndFunc ;---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Child_Process_Library.au3 expandcollapse popup#include "Child_Process_Library_Constants.au3" If $CmdLine[0] = 0 Or Not ($CmdLine[1] == "NewChProcess") Then ParentWinMain() Else StartWinMain() EndIf Func ParentWinMain() $ProcNumA = NewChProcess() $Return = CallChProcess($ProcNumA,"cMsgBoxA",0,10,20,PtrToCallPtr("String")) MsgBox(0,"Parent Process",$Return) $ProcNumB = NewChProcess() $Struct = DllStructCreate("int NumA;Int NumB;WCHAR Text[10]") DllStructSetData($Struct,1,100) DllStructSetData($Struct,2,200) DllStructSetData($Struct,3,"0123456789") $StructPtr = DllStructGetPtr($Struct) $Return = CallChProcess($ProcNumB,"cMsgBoxB",0,10,20,PtrToCallPtr($StructPtr,0,"int NumA;Int NumB;WCHAR Text[10]")) MsgBox(0,"Parent Process",$Return) $ProcNumC = NewChProcess() $Struct = DllStructCreate("int NumA;Int NumB;WCHAR Text[10]") DllStructSetData($Struct,1,100) DllStructSetData($Struct,2,200) DllStructSetData($Struct,3,"0123456789") $StructPtr = DllStructGetPtr($Struct) $StructSize = DllStructGetSize($Struct) $Return = CallChProcess($ProcNumC,"cMsgBoxC",0,10,20,PtrToCallPtr($StructPtr,$StructSize)) MsgBox(0,"Parent Process",CallPtrToPtr($Return,Prohandle_From_ProNum($ProcNumC))) EndFunc Func ChildWinMain() Return True ; False Exit /// True Continue EndFunc Func StartWinMain() $IsChildProcess = True $yCallPtr = Ptr($CmdLine[4]) $ParentProcessID = Int($CmdLine[3]) $yProcessNumber = Int($CmdLine[2]) $ParentProhandle = GetPro_handle(0,$ParentProcessID) cRead_Ptr($ParentProhandle,$yCallPtr,$CallPtr,$CallSize) DllStructSetData($CallStruct,"cFinish",1,$yProcessNumber) DllStructSetData($CallStruct,"CallPtr",$CallPtr,$yProcessNumber) DllStructSetData($CallStruct,"ChProcessID",$ProcessID,$yProcessNumber) cWrite_Ptr($ParentProhandle,$yCallPtr,$CallPtr,$CallSize) While IsParentProcessWork() And ChildWinMain() if DllStructGetData($CallStruct,"TestCall",$yProcessNumber) Then CallFunc() WEnd Exit EndFunc Func IsParentProcessWork($pTime = 5000) if (TimerDiff($pbeginA) < $pTime) Then Return True if Not ProcessExists($ParentProcessID) Then Return False $pbeginA = TimerInit() Return True EndFunc Func cMsgBoxA($vA,$vB,$vC) $String = CallPtrToPtr($vC,$ParentProhandle) ;$vC Is A String Ptr MsgBox(0,"Child Process cMsgBoxA",$vA & " " & $vB & " " & $String ) Return ReturnToReturnCall($vA * $vB) EndFunc Func cMsgBoxB($vA,$vB,$vC) $Struct = CallPtrToPtr($vC,$ParentProhandle) ;$vC Is A Struct Ptr MsgBox(0,"Child Process cMsgBoxB",$vA & " " & $vB ) $Text = "NumA Is " & DllStructGetData($Struct,"NumA") & @CRLF $Text &= "NumB Is " & DllStructGetData($Struct,"NumB") & @CRLF $Text &= "Text Is " & DllStructGetData($Struct,"Text") & @CRLF MsgBox(0,"Child Process cMsgBoxB",$Text) Return ReturnToReturnCall($vA + $vB) EndFunc Func cMsgBoxC($vA,$vB,$vC) $Struct = CallPtrToPtr($vC,$ParentProhandle) ;$vC Is A Bytes Struct Ptr MsgBox(0,"Child Process cMsgBoxC",DllStructGetData($Struct,1) ) $iStruct = DllStructCreate("int NumA;Int NumB;WCHAR Text[10]",DllStructGetPtr($Struct)) $Text = "NumA Is " & DllStructGetData($iStruct,"NumA") & @CRLF $Text &= "NumB Is " & DllStructGetData($iStruct,"NumB") & @CRLF $Text &= "Text Is " & DllStructGetData($iStruct,"Text") & @CRLF MsgBox(0,"Child Process cMsgBoxC",$Text) Return ReturnToReturnCall(PtrToCallPtr("String")) EndFunc Func NewChProcess($WaitChildProcess = True , $Timeout = 5000) ; Calling From Parent Process Only if $IsChildProcess Then Return SetError(1,0,0) ;error 1 if Calling From Child Process if $cMax = $wProcessCount Then Return SetError(2,0,0) ;error 2 Upto Max Of Child dProcess $wProcessCount += 1 DllStructSetData($CallStruct,"cFinish",0,$wProcessCount) $Command = "NewChProcess " & $wProcessCount & " " & $ProcessID & " " & $CallPtr if (@Compiled) Then $ChProcessID = Run(FileGetShortName(@AutoItExe) & " " & $Command) Else $ChProcessID = Run(FileGetShortName(@AutoItExe) & " " & FileGetShortName(@ScriptFullPath) & " " & $Command) EndIf if $WaitChildProcess Then $begin = TimerInit() While Not DllStructGetData($CallStruct,"cFinish",$wProcessCount) And _ ProcessExists($ChProcessID) And TimerDiff($begin) <= $Timeout Sleep(100) WEnd EndIf $Prohandle = GetPro_handle(0,$ChProcessID) if @error Then Return SetError(3,0,0) ; error 3 error In Get Child Process handle DllStructSetData($CallStruct,"ChProcesshandle",$Prohandle,$wProcessCount) ; Return New Child Process Number Return $wProcessCount EndFunc Func CallChProcess($ProcessNum,$FNam,$RtIly,$Pam1 = 0,$Pam2 = 0,$Pam3 = 0 _ , $Pam4 = 0 , $Pam5 = 0 ,$Pam6 = 0,$Pam7 = 0,$Pam8 = 0,$Pam9 = 0,$Pam10 = 0) Local $NumParams = @NumParams - 3 DllStructSetData($CallStruct,"ParamCount",$NumParams) Select Case $NumParams = 1 DllStructSetData($CallStruct,2,$Pam1) Case $NumParams = 2 DllStructSetData($CallStruct,2,$Pam1) DllStructSetData($CallStruct,3,$Pam2) Case $NumParams = 3 DllStructSetData($CallStruct,2,$Pam1) DllStructSetData($CallStruct,3,$Pam2) DllStructSetData($CallStruct,4,$Pam3) Case $NumParams = 4 DllStructSetData($CallStruct,2,$Pam1) DllStructSetData($CallStruct,3,$Pam2) DllStructSetData($CallStruct,4,$Pam3) DllStructSetData($CallStruct,5,$Pam4) Case $NumParams = 5 DllStructSetData($CallStruct,2,$Pam1) DllStructSetData($CallStruct,3,$Pam2) DllStructSetData($CallStruct,4,$Pam3) DllStructSetData($CallStruct,5,$Pam4) DllStructSetData($CallStruct,6,$Pam5) Case $NumParams = 6 DllStructSetData($CallStruct,2,$Pam1) DllStructSetData($CallStruct,3,$Pam2) DllStructSetData($CallStruct,4,$Pam3) DllStructSetData($CallStruct,5,$Pam4) DllStructSetData($CallStruct,6,$Pam5) DllStructSetData($CallStruct,7,$Pam6) Case $NumParams = 7 DllStructSetData($CallStruct,2,$Pam1) DllStructSetData($CallStruct,3,$Pam2) DllStructSetData($CallStruct,4,$Pam3) DllStructSetData($CallStruct,5,$Pam4) DllStructSetData($CallStruct,6,$Pam5) DllStructSetData($CallStruct,7,$Pam6) DllStructSetData($CallStruct,8,$Pam7) Case $NumParams = 8 DllStructSetData($CallStruct,2,$Pam1) DllStructSetData($CallStruct,3,$Pam2) DllStructSetData($CallStruct,4,$Pam3) DllStructSetData($CallStruct,5,$Pam4) DllStructSetData($CallStruct,6,$Pam5) DllStructSetData($CallStruct,7,$Pam6) DllStructSetData($CallStruct,8,$Pam7) DllStructSetData($CallStruct,9,$Pam8) Case $NumParams = 9 DllStructSetData($CallStruct,2, $Pam1) DllStructSetData($CallStruct,3, $Pam2) DllStructSetData($CallStruct,4, $Pam3) DllStructSetData($CallStruct,5, $Pam4) DllStructSetData($CallStruct,6, $Pam5) DllStructSetData($CallStruct,7, $Pam6) DllStructSetData($CallStruct,8, $Pam7) DllStructSetData($CallStruct,9, $Pam8) DllStructSetData($CallStruct,10,$Pam9) Case $NumParams = 10 DllStructSetData($CallStruct,2, $Pam1) DllStructSetData($CallStruct,3, $Pam2) DllStructSetData($CallStruct,4, $Pam3) DllStructSetData($CallStruct,5, $Pam4) DllStructSetData($CallStruct,6, $Pam5) DllStructSetData($CallStruct,7, $Pam6) DllStructSetData($CallStruct,8, $Pam7) DllStructSetData($CallStruct,9, $Pam8) DllStructSetData($CallStruct,10,$Pam9) DllStructSetData($CallStruct,11,$Pam10) EndSelect $yCallPtr = DllStructGetData($CallStruct,"CallPtr",$ProcessNum) $ChProceID = DllStructGetData($CallStruct,"ChProcessID",$ProcessNum) $Prohandle = DllStructGetData($CallStruct,"ChProcesshandle",$ProcessNum) DllStructSetData($CallStruct,"FucName",$FNam) ; Func Name DllStructSetData($CallStruct ,"RtIly",$RtIly) ; Return immediately DllStructSetData($CallStruct,"cFinish",0,$ProcessNum) DllStructSetData($CallStruct,"TestCall",1,$ProcessNum) cWrite_Ptr($Prohandle,$yCallPtr,$CallPtr,$CallSize) Local $BoolA = False , $BoolB = True While ((Not $BoolA) And $BoolB) $BoolA = DllStructGetData($CallStruct,"cFinish",$ProcessNum) $BoolB = ProcessExists($ChProceID) Sleep(100) WEnd if $BoolA Then if $RtIly Then Return SetError(0,0,0) $ReturnPtr = DllStructGetData($CallStruct,"ReturnPtr") Return ReturnCallToReturn($ReturnPtr,$Prohandle) EndIf Return SetError(1,0,0) EndFunc Func CallFunc() $FuncName = DllStructGetData($CallStruct,"FucName") $NumParams = DllStructGetData($CallStruct,"ParamCount") $RtIly = DllStructGetData($CallStruct,"RtIly") ;Return immediately Local $ArgsArray[$NumParams + 1] $ArgsArray[0] = "CallArgArray" Select Case $NumParams = 1 $ArgsArray[1] = DllStructGetData($CallStruct,2) Case $NumParams = 2 $ArgsArray[1] = DllStructGetData($CallStruct,2) $ArgsArray[2] = DllStructGetData($CallStruct,3) Case $NumParams = 3 $ArgsArray[1] = DllStructGetData($CallStruct,2) $ArgsArray[2] = DllStructGetData($CallStruct,3) $ArgsArray[3] = DllStructGetData($CallStruct,4) Case $NumParams = 4 $ArgsArray[1] = DllStructGetData($CallStruct,2) $ArgsArray[2] = DllStructGetData($CallStruct,3) $ArgsArray[3] = DllStructGetData($CallStruct,4) $ArgsArray[4] = DllStructGetData($CallStruct,5) Case $NumParams = 5 $ArgsArray[1] = DllStructGetData($CallStruct,2) $ArgsArray[2] = DllStructGetData($CallStruct,3) $ArgsArray[3] = DllStructGetData($CallStruct,4) $ArgsArray[4] = DllStructGetData($CallStruct,5) $ArgsArray[5] = DllStructGetData($CallStruct,6) Case $NumParams = 6 $ArgsArray[1] = DllStructGetData($CallStruct,2) $ArgsArray[2] = DllStructGetData($CallStruct,3) $ArgsArray[3] = DllStructGetData($CallStruct,4) $ArgsArray[4] = DllStructGetData($CallStruct,5) $ArgsArray[5] = DllStructGetData($CallStruct,6) $ArgsArray[6] = DllStructGetData($CallStruct,7) Case $NumParams = 7 $ArgsArray[1] = DllStructGetData($CallStruct,2) $ArgsArray[2] = DllStructGetData($CallStruct,3) $ArgsArray[3] = DllStructGetData($CallStruct,4) $ArgsArray[4] = DllStructGetData($CallStruct,5) $ArgsArray[5] = DllStructGetData($CallStruct,6) $ArgsArray[6] = DllStructGetData($CallStruct,7) $ArgsArray[7] = DllStructGetData($CallStruct,8) Case $NumParams = 8 $ArgsArray[1] = DllStructGetData($CallStruct,2) $ArgsArray[2] = DllStructGetData($CallStruct,3) $ArgsArray[3] = DllStructGetData($CallStruct,4) $ArgsArray[4] = DllStructGetData($CallStruct,5) $ArgsArray[5] = DllStructGetData($CallStruct,6) $ArgsArray[6] = DllStructGetData($CallStruct,7) $ArgsArray[7] = DllStructGetData($CallStruct,8) $ArgsArray[8] = DllStructGetData($CallStruct,9) Case $NumParams = 9 $ArgsArray[1] = DllStructGetData($CallStruct,2) $ArgsArray[2] = DllStructGetData($CallStruct,3) $ArgsArray[3] = DllStructGetData($CallStruct,4) $ArgsArray[4] = DllStructGetData($CallStruct,5) $ArgsArray[5] = DllStructGetData($CallStruct,6) $ArgsArray[6] = DllStructGetData($CallStruct,7) $ArgsArray[7] = DllStructGetData($CallStruct,8) $ArgsArray[8] = DllStructGetData($CallStruct,9) $ArgsArray[9] =DllStructGetData($CallStruct,10) Case $NumParams = 10 $ArgsArray[1] = DllStructGetData($CallStruct,2) $ArgsArray[2] = DllStructGetData($CallStruct,3) $ArgsArray[3] = DllStructGetData($CallStruct,4) $ArgsArray[4] = DllStructGetData($CallStruct,5) $ArgsArray[5] = DllStructGetData($CallStruct,6) $ArgsArray[6] = DllStructGetData($CallStruct,7) $ArgsArray[7] = DllStructGetData($CallStruct,8) $ArgsArray[8] = DllStructGetData($CallStruct,9) $ArgsArray[9] =DllStructGetData($CallStruct,10) $ArgsArray[10]=DllStructGetData($CallStruct,11) EndSelect if $RtIly Then DllStructSetData($CallStruct ,"cFinish",1,$yProcessNumber) DllStructSetData($CallStruct,"TestCall",0,$yProcessNumber) cWrite_Ptr($ParentProhandle,$yCallPtr,$CallPtr,$CallSize) EndIf $ReturnPtr = Call($FuncName,$ArgsArray) if Not $RtIly Then DllStructSetData($CallStruct ,"cFinish",1,$yProcessNumber) DllStructSetData($CallStruct,"TestCall",0,$yProcessNumber) DllStructSetData($CallStruct,"ReturnPtr",$ReturnPtr) cWrite_Ptr($ParentProhandle,$yCallPtr,$CallPtr,$CallSize) EndIf EndFunc Func CallPtrToPtr($PtrOrStr,$Prohandle) $Struct = DllStructCreate("Byte Type;Int LenAndSize") $Pointer = DllStructGetPtr($Struct) $Size = DllStructGetSize($Struct) cRead_Ptr($Prohandle,$PtrOrStr,$Pointer,$Size) $LenAndSize = DllStructGetData($Struct,2) Switch DllStructGetData($Struct,1) Case 1 $yTagStruct = "Byte Type;Int Len;WCHAR[" & $LenAndSize & "]" $Struct = DllStructCreate($yTagStruct) $Pointer = DllStructGetPtr($Struct) $Size = DllStructGetSize($Struct) cRead_Ptr($Prohandle,$PtrOrStr,$Pointer,$Size) Return SetError(0,1,DllStructGetData($Struct,3)) Case 2 $yTagStruct = "Byte Type;Int Len;Byte[" & $LenAndSize & "]" $Struct = DllStructCreate($yTagStruct) $Pointer = DllStructGetPtr($Struct) $Size = DllStructGetSize($Struct) cRead_Ptr($Prohandle,$PtrOrStr,$Pointer,$Size) $yStruct = DllStructCreate("byte[" & $LenAndSize & "]") $BPtr = DllStructGetPtr($Struct,3) $YPtr = DllStructGetPtr($yStruct) _MemMoveMemory($BPtr,$YPtr,$LenAndSize) Return SetError(0,2,$yStruct) Case 3 $yTagStruct = "Byte Type;Int Size;Byte[" & $LenAndSize & "];WCHAR TagSt[1000]" $Struct = DllStructCreate($yTagStruct) $Pointer = DllStructGetPtr($Struct) $Size = DllStructGetSize($Struct) cRead_Ptr($Prohandle,$PtrOrStr,$Pointer,$Size) $TagSt = DllStructGetData($Struct,4) $yStruct = DllStructCreate($TagSt) $BPtr = DllStructGetPtr($Struct,3) $YPtr = DllStructGetPtr($yStruct) _MemMoveMemory($BPtr,$YPtr,$LenAndSize) Return SetError(0,3,$yStruct) EndSwitch Return SetError(2,0,0) EndFunc Func PtrToCallPtr($PtrOrStr,$Size = 0,$yTagStruct = -1) Local $Struct Select Case IsString($PtrOrStr) $cLen = StringLen($PtrOrStr) $Struct = DllStructCreate("Byte Type;Int Len;WCHAR[" & $cLen & "]") DllStructSetData($Struct,1,1) DllStructSetData($Struct,2,$cLen) DllStructSetData($Struct,3,$PtrOrStr) Case Else Select Case $yTagStruct == -1 $yTagStruct = "Byte Type;Int Size;Byte[" & $Size & "]" $Struct = DllStructCreate($yTagStruct) DllStructSetData($Struct,1,2) DllStructSetData($Struct,2,$Size) _MemMoveMemory($PtrOrStr,DllStructGetPtr($Struct,3),$Size) Case Else if StringLen($yTagStruct) > 1000 Then Return SetError(1,0,0) if $Size = 0 Then $Size = DllStructGetSize(DllStructCreate($yTagStruct)) $cTagStruct = "Byte Type;Int Size;Byte[" & $Size & "];WCHAR TagSt[1000]" $Struct = DllStructCreate($cTagStruct) DllStructSetData($Struct,1,3) DllStructSetData($Struct,2,$Size) DllStructSetData($Struct,4,$yTagStruct) _MemMoveMemory($PtrOrStr,DllStructGetPtr($Struct,3),$Size) EndSelect EndSelect StructSetGlobal($Struct) ; Read Text In StructSetGlobal Func Return SetError(0,0,DllStructGetPtr($Struct)) EndFunc Func StructSetGlobal($Struct) ; StructSetGlobal ; Set Struct In Global if Struct From Child Process and Read it From Parent Process Or Struct From ;Parent Process and Read it From Child Process ;You can Set 20 Structs before deleting the first Struct /// $GlobalStNum = 20 Switch $GlobalStNum Case $MaxGlobal $GlobalStArray[$GlobalStNum - 1] = $Struct $GlobalStNum = 1 Return $GlobalStNum Case Else $GlobalStArray[$GlobalStNum - 1] = $Struct $GlobalStNum += 1 Return $GlobalStNum EndSwitch EndFunc Func ReturnCallToReturn($ReturnPtr,$Prohandle) $Struct = DllStructCreate("Double") $Pointer = DllStructGetPtr($Struct) $Size = DllStructGetSize($Struct) cRead_Ptr($Prohandle,$ReturnPtr,$Pointer,$Size) Return DllStructGetData($Struct,1) EndFunc Func ReturnToReturnCall($iData) $ReturnSt = DllStructCreate("Double") ; On Global DllStructSetData($ReturnSt,1,$iData) Return DllStructGetPtr($ReturnSt) EndFunc Func Prohandle_From_ProNum($ProNumber = -1) if $ProNumber = -1 Then Return $ParentProhandle Return DllStructGetData($CallStruct,"ChProcesshandle",$ProNumber) EndFunc Func GetPro_handle($eProcessNumber = 0,$iProcessID = -1) if $iProcessID = -1 Then $iProcessID = DllStructGetData($CallStruct,"ChProcessID",$eProcessNumber) $ihProcess = _WinAPI_OpenProcess($iPROCESS_ALL_ACCESS,False,$iProcessID) Return SetError(@error,0,$ihProcess) EndFunc Func cWrite_Ptr($ihProcess,$Address,$Pointer,$Size) Local $iWritten $Return = _WinAPI_WriteProcessMemory($ihProcess,$Address,$Pointer,$Size,$iWritten) Return SetError($Return == False,0,$Return) EndFunc Func cRead_Ptr($ihProcess,$Address,$Pointer,$Size) Local $iRead $Return = _WinAPI_ReadProcessMemory($ihProcess,$Address,$Pointer,$Size,$iRead) Return SetError($Return == False,0,$Return) EndFunc Func CloseProcesshandle($ihProcess) Return _WinAPI_CloseHandle($ihProcess) EndFunc Child_Process_Library_Constants.au3 #include <WinAPI.au3> #include <Memory.au3> #include <Math.au3> Global $MaxGlobal = 20 , $IsChildProcess = 0 , $yCallPtr = 0 , $cMax = 256,$ParentProhandle Global $iSYNCHRONIZE = ( 0x00100000 ) , $iSTANDARD_RIGHTS_REQUIRED = (0x000F0000) Global $iPROCESS_ALL_ACCESS = ( $iSTANDARD_RIGHTS_REQUIRED + $iSYNCHRONIZE + 0xFFF) Global $yProcessNumber = 0 , $GlobalStArray[$MaxGlobal] ,$wProcessCount = 0,$ihProcess = 0 Global $pbeginA = TimerInit() , $GlobalStNum = 1 , $ParentProcessID = 0 , $ReturnSt ; $yProcessNumber = 0 // Child Process Number In Child Process ; $wProcessCount = 0 // Count Of Child Process In Parent Process ; $ParentProcessID = 0 /// Parent Process ID In Child Process ; $cMax = 256 /// Max Of Child Processs ; $GlobalStArray // Read Text In StructSetGlobal Func ; $MaxGlobal // Read Text In StructSetGlobal Func $tagCallStruct = "int ParamCount;Double aData;Double bData;Double cData;Double dData;Double eData;" & _ "Double fData;Double gData;Double hData;Double iData;Double jData;Ptr ReturnPtr;WCHAR FucName[100];" & _ "int RtIly;int cFinish[" & $cMax & "];int TestCall[" & $cMax & "];Ptr CallPtr[" & $cMax & "];int " & _ "ChProcessID[" & $cMax & "];handle ChProcesshandle["& $cMax & "]" Global $CallStruct = DllStructCreate($tagCallStruct) Global $CallSize = DllStructGetSize($CallStruct) Global $CallPtr = DllStructGetPtr($CallStruct) Global $ProcessID = _WinAPI_GetCurrentProcessID() Edited March 24, 2020 by wolf9228 صرح السماء كان هنا Link to comment Share on other sites More sharing options...
seadoggie01 Posted March 22, 2020 Share Posted March 22, 2020 Quick hint... instead of filling your DllStruct with a giant select case and writing manually all of the options, you can do this: ; Load all of the parameters into an array Local $aPam = [$Pam1, $Pam2, ...] ; Loop through each parameter For $i=0 To $NumParams DllStructSetData($CallStruct, $i + 2, $aPam[$i]) Next ; And later... to fetch the data, just loop For $i=1 To $NumParams $ArgsArray[$i] = DllStructGetData($CallStruct, $i+1) Next Your way works, but this looks a lot cleaner and is easier to understand All my code provided is Public Domain... but it may not work. Use it, change it, break it, whatever you want. Spoiler My Humble Contributions:Personal Function Documentation - A personal HelpFile for your functionsAcro.au3 UDF - Automating Acrobat ProToDo Finder - Find #ToDo: lines in your scriptsUI-SimpleWrappers UDF - Use UI Automation more Simply-erKeePass UDF - Automate KeePass, a password managerInputBoxes - Simple Input boxes for various variable types Link to comment Share on other sites More sharing options...
wolf9228 Posted March 22, 2020 Author Share Posted March 22, 2020 19 minutes ago, seadoggie01 said: Quick hint... instead of filling your DllStruct with a giant select case and writing manually all of the options, you can do this: ; Load all of the parameters into an array Local $aPam = [$Pam1, $Pam2, ...] ; Loop through each parameter For $i=0 To $NumParams DllStructSetData($CallStruct, $i + 2, $aPam[$i]) Next ; And later... to fetch the data, just loop For $i=1 To $NumParams $ArgsArray[$i] = DllStructGetData($CallStruct, $i+1) Next Your way works, but this looks a lot cleaner and is easier to understand Thank you This is for more speed because the loop requires more time than the keywords select ... Case ... EndSelect صرح السماء كان هنا Link to comment Share on other sites More sharing options...
argumentum Posted March 22, 2020 Share Posted March 22, 2020 46 minutes ago, wolf9228 said: This is for more speed because the loop requires more time than the keywords select ... Case ... EndSelect ..then use Switch. Is faster yet Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
argumentum Posted March 22, 2020 Share Posted March 22, 2020 ...an example would be welcomed too.😁 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
seadoggie01 Posted March 22, 2020 Share Posted March 22, 2020 49 minutes ago, wolf9228 said: This is for more speed because the loop requires more time than the keywords select ... Case ... EndSelect For fewer than 10 arguments? How long does that really save? If you're looking for that kind of speed, you're looking at the wrong programming language All my code provided is Public Domain... but it may not work. Use it, change it, break it, whatever you want. Spoiler My Humble Contributions:Personal Function Documentation - A personal HelpFile for your functionsAcro.au3 UDF - Automating Acrobat ProToDo Finder - Find #ToDo: lines in your scriptsUI-SimpleWrappers UDF - Use UI Automation more Simply-erKeePass UDF - Automate KeePass, a password managerInputBoxes - Simple Input boxes for various variable types Link to comment Share on other sites More sharing options...
wolf9228 Posted March 23, 2020 Author Share Posted March 23, 2020 On 3/22/2020 at 6:49 AM, argumentum said: ..then use Switch. Is faster yet The speed difference between the keyword Select and the keyword Switch is very small, however I did not think of that, thank you. I modified the keywords during the new example Download example ... Thank you. argumentum 1 صرح السماء كان هنا Link to comment Share on other sites More sharing options...
wolf9228 Posted March 23, 2020 Author Share Posted March 23, 2020 On 3/22/2020 at 6:55 AM, seadoggie01 said: For fewer than 10 arguments? How long does that really save? If you're looking for that kind of speed, you're looking at the wrong programming language Autoit is a wonderful language, speed is not required in any case ... to learn some simple programs, the Autoit language meets the purpose, but when performing an process that performs the task of communication, the code for this process must be fast ... Thank you . صرح السماء كان هنا Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now