ramadash Posted September 4, 2006 Share Posted September 4, 2006 (edited) on post 2 you will find functions to remotly call the call() functions with unlimited parameters.hey all, this is the first script I post here I hope it meet's the requirements to post in this forum (as i didnt see any rules stickyed I assume that its ok). I would first like to thank's Nomad for his nice memory include (you need it also) find it here: http://www.autoitscript.com/forum/index.ph...st&p=201269At first I was looking at a way to transfer data btw scripts, I found a couple of ways, but now I needed a function to remotly call an internal function from a plugin .au3. Well this works so far, I don't think it can lead to an UDF because that it would need to be implemented in each script differently depending on the usage you want to do with it. This is designed to eventually use the CALL() function with CallArgs array to pass random parameters to functions. But im sure that alot of other uses could be found for this. (the API call to sendmessage is the only thing I found to transfer data and it only support 2 params, and it dosent even support strings) so wich this you can pass as much params as you want using only 1 SendMessage.ill try to make better explanations im not very good with english.ok what this script does:-Main.exe will idle (you need to run it first)-When plugin.exe is lauched, it will create the structure defined in the source and send Remote_Function call to main.exe and pass the pointer adress of the struct to it-when main.exe receive the message, it will open the memory of plugin.exe, create a new structure that is the same size as set by plugin in "HKEY_LOCAL_MACHINE\SOFTWARE\autoit3", "StructTypeString01" (dont worry it gets deleted when the operation is done), it will then read the memory at the passed pointer and copy it at the newly created structure pointer.ok so basically it just copy the struct lol.. I havent been able to get a pointer for the structure create in main, no clue why, but I had to use byref to set a struct.ok so now the source, please give me feedbacks! I will also update this frequently-plugin.au3 (this is the file that need's editing)global $StructTypeString = "int;char[128];int;int";set the structure types here global $STRUCT = DllStructCreate( $StructTypeString ) DllStructSetData( $STRUCT, 1, 555 );set the structure values here DllStructSetData( $STRUCT, 2, "this is a string" ) DllStructSetData( $STRUCT, 3, 777 ) DllStructSetData( $STRUCT, 4, 888 ) ;No editing needed below this point RemoteFunc( WinGetHandle("myTest"), 10000, DllStructGetPtr( $STRUCT ), $StructTypeString ) Func RemoteFunc($window, $functionID, $wparam = 0, $lparam = 0) $dll = DllOpen("user32.dll") RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\autoit3", "StructTypeString01", "REG_SZ", $StructTypeString);dont worry this gets deleted after the call DllCall($dll, "none", "SendMessage","hwnd", $window, _ "int", $functionID, "ptr", $wparam, "str", $lparam) DllClose( $dll ) $STRUCT = 0 exit EndFunc-main.au3expandcollapse popup#include <GUIConstants.au3> #include <memory.au3> ;Editing of this file is not needed ( well except if you want to add features ) global $memHANDLE, $StructTypeString $CMD_Test = 10000 $mygui = GuiCreate("myTest",1,1) GUIRegisterMsg($CMD_Test, "Rebuild_Struct") func Rebuild_Struct($hWndGUI, $MsgID, $ptr, $useless ) $StructTypeString = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\autoit3", "StructTypeString01") dim $v_buffer $memHANDLE = OpenMem( "Plugin.exe" ) _MemoryGetStruct( $ptr , $memHandle, $v_buffer, $StructTypeString ) $fooError = @error if $fooError > 0 then MsgBox( 0, "", "Error reading memory, @error= " & $fooError & " " & $StructTypeString ) exit EndIf $MaxIndex = StringSplit( $StructTypeString, ";" ) dim $debugString for $i = 1 to $MaxIndex [0] $debugString &= " " & DllStructGetData( $v_buffer, $i ) Next MsgBox( 0, "", $debugString ) $v_buffer = 0;free mem used by struct _MemoryClose( $memHANDLE ) if @error then MsgBox( 0, "", "Error closing memory" ) Regdelete("HKEY_LOCAL_MACHINE\SOFTWARE\autoit3", "StructTypeString01" ) exit EndFunc While 1 Sleep(100) WEnd ;return a memory handle func OpenMem( $process ) $pid = ProcessExists ( $process ) if not $pid then MsgBox( 0, "", "ERROR: " & $process & " process does not exist" ) exit EndIf ;open main memory handle $mem = _memoryOpen( $pid ) $fooError = @error if $fooError > 0 then MsgBox( 0, "", "error opening " & $process & " , @error=" & $fooError ) Exit Else MsgBox( 0, "", $process & " memory open sucessfully" ) EndIf return $mem EndFunc ;based off Nomad _MemoryRead() functions, credits to him :D ;using byref is the only way I was able to keep the struct valid outside the function ;error values are the same as _MemoryRead() ;return value, 1=sucess 0=failed func _MemoryGetStruct( $iv_Address, $ah_Handle, byref $v_buffer, $sv_Type = 'dword' ) If Not IsArray($ah_Handle) Then SetError(1) Return 0 EndIf $v_Buffer = DllStructCreate($sv_Type) If @Error Then SetError(@Error + 1) Return 0 EndIf DllCall($ah_Handle[0], 'int', 'ReadProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '') If Not @Error Then return 1 Else SetError(6) Return 0 EndIf EndFunc Edited September 5, 2006 by ramadash Link to comment Share on other sites More sharing options...
ramadash Posted September 5, 2006 Author Share Posted September 5, 2006 the following scripts will wrap the call() function so it can be called from a run /autoitexec "myscript" (virtually giving all functions in the main script to the executed script) what this will do (compile them and run main first for an example) : 1. Main.exe get's loaded first, this script hold all the functions 2. When you load Plugin.exe, it will send a message to Main.exe, telling it to execute the specified functions (see top of plugin.au3) 3. Main.exe will execute the functions 4. Plugin.exe will close main.exe after all functions are executed -main.au3expandcollapse popup#include <GUIConstants.au3> #include <memory.au3> #include <array.au3> ;EXAMPLE FUNCTIONS func msgbox1($var1, $var2, $var3, $var4) MsgBox( 0, "", "MsgBox1(): " & $var1 & " " & $var2 & " " & $var3 & " " & $var4 ) EndFunc func msgbox2($var1,$var2) MsgBox( 0, "", "MsgBox2(): " & $var1 & " " & $var2 ) EndFunc func MsgBox3( $OneVar ) MsgBox( 0, "", "MsgBox3(): This function have only 1 variable, this variable is: " & $onevar ) EndFunc func msgbox4() MsgBox( 0, "", "MsgBox4(): This function have no parameters passed to it" ) EndFunc #region call function wrapper (server) ;Editing of this file is not needed ( well except if you want to add features ) $CMD_CallWrapper = 10000 $CMD_Quit = 10001 $mygui = GuiCreate("myTest",1,1) GUIRegisterMsg($CMD_CallWrapper, "CallWrapper" ) GUIRegisterMsg( $CMD_Quit, "Quit" ) While 1 Sleep(100) WEnd func Quit() Exit EndFunc ;TODO get rid of regread (yes im lazy...) - handle errors with setting @error instead of msgbox-exit func CallWrapper($hWndGUI, $MsgID, $ptr, $args ) switch $args case 0 call ( RegRead( "HKEY_LOCAL_MACHINE\SOFTWARE\autoit3", "Param1" ) ) RegDelete("HKEY_LOCAL_MACHINE\SOFTWARE\autoit3", "Param1") case 1 $arg = StringSplit( RegRead( "HKEY_LOCAL_MACHINE\SOFTWARE\autoit3", "Param1" ) , "." ) RegDelete( "HKEY_LOCAL_MACHINE\SOFTWARE\autoit3", "Param1" ) call ( $arg[1], $arg[2] ) case 2 $StructTypeString = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\autoit3", "StructTypeString01") Regdelete("HKEY_LOCAL_MACHINE\SOFTWARE\autoit3", "StructTypeString01" ) dim $v_buffer $memHANDLE = OpenMem( "Plugin.exe" ) _MemoryGetStruct( $ptr , $memHandle, $v_buffer, $StructTypeString ) $fooError = @error if $fooError > 0 then MsgBox( 0, "", "Error reading memory, @error= " & $fooError & " " & $StructTypeString ) exit EndIf $MaxIndex = StringSplit( $StructTypeString, ";" ) $funcName = DllStructGetData( $v_buffer, $MaxIndex[0] ) dim $fooArgs[ $MaxIndex[0] ] for $i = 0 to $maxindex[0] -1 $fooArgs[ $i ] = DllStructGetData( $v_buffer, $i+1 ) Next _ArrayPop( $fooArgs ) call ( $funcName, $fooArgs ) if @error then MsgBox( 0, "", "Function " & $funcName & " does not exist" ) EndIf $v_buffer = 0;free mem used by struct _MemoryClose( $memHANDLE ) if @error then MsgBox( 0, "", "Error closing memory" ) EndSwitch EndFunc ;return a memory handle func OpenMem( $process ) $pid = ProcessExists ( $process ) if not $pid then MsgBox( 0, "", "ERROR: " & $process & " process does not exist" ) exit EndIf ;open main memory handle $mem = _memoryOpen( $pid ) $fooError = @error if $fooError > 0 then MsgBox( 0, "", "error opening " & $process & " , @error=" & $fooError ) Exit EndIf return $mem EndFunc ;based off Nomad _MemoryRead() functions, credits to him :D ;using byref is the only way I was able to keep the struct valid outside the function ;error values are the same as _MemoryRead() ;return value, 1=sucess 0=failed func _MemoryGetStruct( $iv_Address, $ah_Handle, byref $v_buffer, $sv_Type = 'dword' ) If Not IsArray($ah_Handle) Then SetError(1) Return 0 EndIf $v_Buffer = DllStructCreate($sv_Type) If @Error Then SetError(@Error + 1) Return 0 EndIf DllCall($ah_Handle[0], 'int', 'ReadProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '') If Not @Error Then return 1 Else SetError(6) Return 0 EndIf EndFunc #endregion -plugin.au3expandcollapse popup;supports STRING and INT ->ONLY<- global $MainWindowName = "myTest" ; call --> msgbox1($var1, $var2, $var3, $var4) dim $arg1[4] = [ "var1", "var2", "var3", "var4" ] CallFunction ( "msgbox1", $arg1 ) ;call --> msgbox2($var1,$var2) dim $arg2[2] = [ 1, " previous arg was an integer" ] CallFunction ( "msgbox2", $arg2 ) ;call --> MsgBox3( $OneVar ) CallFunction ( "MsgBox3" , "yahooo" ) ;call --> MsgBox4() CallFunction( "MsgBox4" ) RemoteFunc( WinGetHandle( $MainWindowName ), 10001 );kill main.exe #region call function wrapper (client) func CallFunction( $FuncName, $args = 0 ) if $args == 0 then RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\autoit3", "Param1", "REG_SZ", $FuncName ) RemoteFunc( WinGetHandle( $MainWindowName ), 10000, 0, 0 ) Return elseif IsArray($args) == 0 then RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\autoit3", "Param1", "REG_SZ", $FuncName & "." & $args) RemoteFunc( WinGetHandle( $MainWindowName ), 10000, 0, 1 ) return Else local $StructTypeString= "char[13];", $Struct, $debugString for $var in $args if IsInt( $var ) then $StructTypeString &= "int;" elseif IsString ( $var ) then $StructTypeString &= "char[" & ( StringLen( $var ) + 1 ) & "];" Else MsgBox( 0, "", "Function() Error: " & $var & " is not an int and not a string" ) EndIf Next $StructTypeString &= "char[" & StringLen( $funcName ) + 1 & "]" $Struct = DllStructCreate( $StructTypeString ) DllStructSetData( $Struct, 1, "CallArgArray" ) for $i = 1 to UBound( $args ) DllStructSetData( $Struct, $i+1, $args[$i-1] ) next DllStructSetData( $Struct, Ubound( $args ) + 2, $funcName ) RemoteFunc( WinGetHandle( $MainWindowName ), 10000, DllStructGetPtr( $Struct ), 2, $StructTypeString ) EndIf EndFunc Func RemoteFunc($window, $functionID, $wparam = 0, $lparam = 0, $StructTypeString = "") $dll = DllOpen("user32.dll") RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\autoit3", "StructTypeString01", "REG_SZ", $StructTypeString);dont worry this gets deleted after the call DllCall($dll, "none", "SendMessage","hwnd", $window, _ "int", $functionID, "ptr", $wparam, "int", $lparam) DllClose( $dll ) $STRUCT = 0 EndFunc #endregion Link to comment Share on other sites More sharing options...
ramadash Posted December 21, 2006 Author Share Posted December 21, 2006 hey I havent been here in awhile just wondering if anyone tryied this Link to comment Share on other sites More sharing options...
sohfeyr Posted January 2, 2007 Share Posted January 2, 2007 I tried it and found it impressive as a proof of concept. How I, personally, would use it is a little less clear, but that's just my situation. I don't suppose you've tried sharing COM objects between scripts? That could be insanely useful when used with a Dictionary or SortedList object. Mine:Time Functions - Manipulate the system clock! | WinControlList (WinGetClassList++) | .Net Setup Wrapper, Detect or install .Net | Writing and using a VB .NET COM object in AutoItNot mine, but highly recommended:AutoItTreeViewExtension plugin | Menu code | Callback helper dll | Auto3Lib - Control the uncontrollable | Creating COM objects in AutoIt | Using .Net framework classes in AutoIt Link to comment Share on other sites More sharing options...
ramadash Posted April 7, 2007 Author Share Posted April 7, 2007 no i never tryed this i dont know if i would have the skills necessary to do that, might look into it someday Link to comment Share on other sites More sharing options...
piccaso Posted April 7, 2007 Share Posted April 7, 2007 does the os support marshalling objects?imo its a bit easier to use WM_COPYDATA to share data between processes... CoProc Multi Process Helper libraryTrashBin.nfshost.com store your AutoIt related files here!AutoIt User Map Link to comment Share on other sites More sharing options...
Uten Posted April 7, 2007 Share Posted April 7, 2007 There are also some blocking issues. What if the user use sleep in one of the functions? But all in all, nice sample... Please keep your sig. small! Use the help file. Search the forum. Then ask unresolved questions :) Script plugin demo, Simple Trace udf, TrayMenuEx udf, IOChatter demo, freebasic multithreaded dll sample, PostMessage, Aspell, Code profiling 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