GreenCan

Shared memory variables demo

13 posts in this topic

#1 ·  Posted (edited)

There are already a few examples of sharing variables via memory on this forum but you may like this one.

There are 2 scripts:

1. Example_Sharing_Memory_Var.au3 is the calling application (I call it the mother application)

2. Sharing_Memory_Client.au3 is the client application

The mother Application is creating the structures for the different variables to be shared across applications (could be more than 2 of course)

Once the structures are defined and assigned, the child application is launched bythe mother with command line parameters that contains the PID of the mother and the addresses of the pointers to the shared variables.

In this example the dialogue is bi-directional:

- The mother application changes background colour as requested by the child application.

- The Child application GUI will move position on request of the mother.

- Both GUIs will force shutdown of the other application by pressing the Stop button (I quit, you quit…)

- The mother application will send any text that is entered in the input field (press enter to confirm)

- The mother application can send two commands to the child application, ‘color’ and ‘quit’. Color will force a color change for both GUIs, Quit will be suicidal for the mother application.

Pre-requisite:

- Don’t change the name of the child application unless you change the name in the calling application

The script uses Nomad memory UDF, I included it in the script, so you don't have to search for it.

GreenCan

Example_Sharing_Memory_Var.au3

#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.0.0
 Author:         GreenCan

 Script Function: Example_Sharing_Memory_Var.au3
 
    Example of sharing variables between applications
    
    This script will start another application 'Sharing_Memory_Client.au3' 
    
    It will pass it's PID and 3 pointers to the variables to be shared
    It will communicate with that application by changing the content of the variables:
    
    The child application can also change the content (background color) and can force the shutdown of this application
    
#ce ----------------------------------------------------------------------------

#include <GUIConstantsEx.au3>

; initial values for backround color and corner position
Global $BackgroundColor = 0x01398E ; initial value
Global $CornerPosition = 1, $add = True ; corner variables
; set GUI
$Gui = GUICreate("Calling Application", 300, 200, 100, 100)

GuiCtrlCreateLabel("Example of sharing variables across applications", 5, 10,290,20)
GUICtrlSetFont (-1, 10) 
GUICtrlSetColor ( -1, 0xFFFFFF)
$LabelColor = GuiCtrlCreateLabel("Color: " & $BackgroundColor, 5, 35,290,40)
GUICtrlSetColor ( $LabelColor, 0xFFFFFF)
GUICtrlSetFont (-1, 10) 

$LastMessage = GuiCtrlCreateLabel("Type something and press enter", 5, 80,290,60)
GUICtrlSetColor ( -1, 0xFFFFFF)
GUICtrlSetFont (-1, 10) 
$Input = GUICtrlCreateInput("", 5, 140, 290, 21)
GUICtrlSetTip ( -1 , "You can type anything but only 2 commands will be understood by the client:" & @CR & " Type 'Color' to force a color change" & @CR & " Type 'Quit' to force the client to quit" )

Local $ok = GUICtrlCreateButton("Stop", 5, 170, 70,22 )
Local $Corner = GUICtrlCreateButton("Change Corner", 195, 170, 100,22 )

;   Create the structure
$struct = "int color;int position;char var[128]"
$Structure=DllStructCreate($struct) 
if @error Then
    MsgBox(0,"","Error in DllStructCreate " & @error);
    exit
endif
DllStructSetData($Structure,"color",$BackgroundColor) ; sets the value of color at $BackgroundColor
DllStructSetData($Structure,"position",$CornerPosition) ; sets the value of corner position 

; get the pointers
$Pointer1 = DllStructGetPtr($Structure,"color") ; Returns the pointer to the color
$Pointer2 = DllStructGetPtr($Structure,"position") ; Returns the pointer to the position
$Pointer3 = DllStructGetPtr($Structure,"var") ; Returns the pointer to the position

ConsoleWrite(@AutoItPID & @CR & $Pointer1 & @CR & $Pointer2 & @CR & $Pointer3 & @CR )

;  Start the client application with 4 parameters:
;   the PID of the calling program (this example)
;   the 3 pointers of the shared variables 

If FileExists(@ScriptDir & "\" & "Sharing_Memory_Client.exe") = 1 Then
    $return = Run("Sharing_Memory_Client.exe " & @AutoItPID & " " & $Pointer1 & " " & $Pointer2 & " " & $Pointer3,  @ScriptDir) 
Else
    If FileExists(@ScriptDir & "\" & "Sharing_Memory_Client.au3") = 1 Then
        $AutoItexePath = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "InstallDir");betaInstallDir for beta 
        $ToRun = '"' & $AutoItexePath & '\AutoIt3.exe "' & ' "' & @ScriptDir & '\Sharing_Memory_Client.au3"' & ' "' & @AutoItPID &'" "' & $Pointer1 & '" "' & $Pointer2 & '" "' & $Pointer3 & '"'
        Run($ToRun) 
    Else
        MsgBox(48, "Error" , "'Sharing_Memory_Client.au3' not found" & @CR & "Both applications should be in the same folder.")
        Exit
    EndIf
EndIf

$OldValue = 0
GUISetState()

While 1
    
    $msg = GUIGetMsg()
    Select
        
    Case $msg = $Input
        GUICtrlSetData ($LastMessage,  "Sent: " & GUICtrlRead($Input))
        ; set the string into the memory
        DllStructSetData($Structure,"var", GUICtrlRead($Input))
        GUICtrlSetData ( $Input, "")
        
    Case $msg = $GUI_EVENT_CLOSE 
        DllStructSetData($Structure,"color",0) ; exit value for child application
        ;Exit
    Case $msg = $ok
        DllStructSetData($Structure,"color",0) ; exit value for child application
        ;Exit   
    Case $msg = $Corner
        ; change position 1, 2 and 3
        
        If $CornerPosition = 3 Then 
            $add = False
        ElseIf $CornerPosition = 1 Then
            $add = True
        EndIf
        If $add = True Then
            $CornerPosition += 1
        Else
            $CornerPosition -= 1
        EndIf
        DllStructSetData($Structure,"position",$CornerPosition) ; exit value for child application
    EndSelect   
    
    $NewValue = DllStructGetData($Structure,"color") ; Pick up the value from the shared memory
    $NewPosition = DllStructGetData($Structure,"position") ; Pick up the value from the shared memory
    
;ConsoleWrite(Hex($NewValue) & " " & $NewPosition & @CR)

    If $NewValue = -1 Then ; Shutdown request from child
        GUICtrlSetData ( $LabelColor,"Exit value: " & $NewValue & @CR & "Child application requests Shutdown")
        Beep(3000,150)
        sleep(3000)
        Exit
    EndIf

    If $OldValue <> $NewValue Then ; change color
        $BackgroundColor = $NewValue
        GUISetBkColor( $BackgroundColor, $Gui)
        GUICtrlSetData ( $LabelColor, "Color: 0x" & Hex($BackgroundColor) )
        $OldValue = $NewValue
    EndIf
        
WEnd

Sharing_Memory_Client.au3

#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.0.0
 Author:         GreenCan

 Script Function: Sharing_Memory_Client.au3
 
    Child application started by Example_Sharing_Memory_Var.au3
    
 Pre-requisite:
    1. Do NOT change the name of the script as it is started by Example_Sharing_Memory_Var.au3
    
 This is the child application that is started by the mother application
 The child receives the PID and the pointers so it can access the variables 
    
 Credits: Thanks to following contributors
    - This source includes Memory UDF library by Nomad
    
#ce ----------------------------------------------------------------------------

; #include "memory2.au3" 
#include <GUIConstantsEx.au3>

If $CmdLine[0] <> 4 Then Exit ; require PID, pointer1 and pointer2
    
; set GUI
$GuiWidth = 300
$GuiHeight = 300
$Gui = GUICreate("Child Application", $GuiWidth, $GuiHeight, @DesktopWidth - $GuiWidth - 100, @DesktopHeight - $GuiHeight - 100)


Global $PID = $CmdLine[1] 
Global $Pointer1 = $CmdLine[2] 
Global $Pointer2 = $CmdLine[3] 
Global $Pointer3 = $CmdLine[4] 

; $Pointer1 = initial value of color passed by the mother application
; the child application (this script) will also use $Pointer1 to communicate that it's stops (by setting $Pointer1 to -1 )
$Color = Read_Memory($PID, $Pointer1) 
; $Pointer2 = initial value of corner position passed by the mother application
$Position = Read_Memory($PID, $Pointer2) 
; initial value of passed char String
$Char = ""

GuiCtrlCreateLabel("Child application" , 5, 5,$GuiWidth - 10,20)
GUICtrlSetColor ( -1, 0xFFFFFF)
GUICtrlSetFont (-1, 10) 
Local $LabelColor = GuiCtrlCreateLabel("The Application will stop when the mother application Quits", 5, 30,$GuiWidth - 10,50)
GUICtrlSetColor ( $LabelColor, 0xFFFFFF)
GUICtrlSetFont (-1, 10) 
Local $GUIEdit=GUICtrlCreateEdit ( "" , 5, $GuiHeight - 235, $GuiWidth - 10, 195)

Local $Stop = GUICtrlCreateButton("Stop", ($GuiWidth/2) - 35, $GuiHeight -30, 70,22 )

GUISetState()
; show the pointers
GUICtrlSetData ( $GUIEdit, "Pointer address 1: " & $Pointer1 & @CRLF & "            address 2: " & $Pointer2 & @CRLF & "            address 3: " & $Pointer3 & @CRLF , "append")

Color()

While 1
    
    $msg = GUIGetMsg()
    If $msg = $Stop Then
        Write_Memory($PID, $Pointer1, -1) ; communicate the exit value to the mother application
        Exit        
    EndIf           
    
    ; if the mother application is closed, the the value will be set to -1 and the child will close too
    $exitValue =  Read_Memory($PID, $Pointer1, "int")
    If $exitValue = 0 Then 
        Quit()
    Else
        ; the mother application requests the child application to change corner if the value of $Pointer2 changes
        $newPosition =  Read_Memory($PID, $Pointer2)
        If $Position <> $newPosition Then
            GUICtrlSetData ( $GUIEdit, "Request from mother to change corner to: " & $newPosition & @CRLF  , "append" )             
            $Position = $newPosition
            If $Position = 1 Then ; Right Lower corner
                WinMove($Gui, "", @DesktopWidth - $GuiWidth - 100, @DesktopHeight - $GuiHeight - 100) 
            ElseIf $Position = 2 Then ; Left Lower corner
                WinMove($Gui, "", 100, @DesktopHeight - $GuiHeight - 100) 
            ElseIf $Position = 3 Then ; Right Upper corner
                WinMove($Gui, "", @DesktopWidth - $GuiWidth - 100, 100) 
            EndIf
        EndIf
        
        ; the mother application sents a character string
        $Char = Read_Memory($PID, $Pointer3, "char var4[128]") 
        If $Char <> "" Then
            Write_Memory($PID, $Pointer3, "", "char var4[128]") ; empty value in memory
            If StringUpper(StringStripWS ($Char,3)) = "QUIT" Then 
                GUICtrlSetData ( $GUIEdit, "Received command" & ": " & $Char  & @CRLF  , "append" )
                Quit()
            ElseIf StringUpper(StringStripWS ($Char,3)) = "COLOR" Then 
                GUICtrlSetData ( $GUIEdit, "Received command" & ": " & $Char  & @CRLF  , "append" )
                Color()
            Else
                GUICtrlSetData ( $GUIEdit, "Received" & ": " & $Char  & @CRLF  , "append" )
                ;TrayTip("text", $Char, 5)
            EndIf
        EndIf
        
        ; change background color and sent to the mother application 
        $randomizer = Random(1,600,1)
        If $randomizer = 1 Then Color()
    EndIf

WEnd
#FUNCTION# ==============================================================
Func Color()
    $Color = Random(1,30000000,1) ; new background color
    GUISetBkColor( $Color, $Gui)
    Write_Memory($PID, $Pointer1, $Color, "int") ; set the new value to be returned to the mother application
    GUICtrlSetData ( $GUIEdit, "Sent Color Change: 0x" & Hex($Color) & @CRLF  , "append" )  
EndFunc ;==>Color
#FUNCTION# ==============================================================
Func Quit()
    GUICtrlSetData ( $GUIEdit, "Mother application requests Shutdown" & @CRLF & @CRLF & "Shutdown within 3 seconds", "append")
    Beep(4000,150)
    sleep(3000)  ; wait 3 secs before closing
    ; You ask me to quit but you Quit too...
    Write_Memory($PID, $Pointer1, -1) ; communicate the exit value to the mother application
    Exit
EndFunc ;==>Quit
#FUNCTION# ==============================================================
Func Write_Memory($_PID, $_Pointer, $_Value, $_VarType = "int")
    ; This function will replace a value in memory, allocated to the calling application 
    Local $DllHandle = _MemoryOpen($_PID) ; Open the memory allocated by the PID from the calling application
    Local $Data = _MemoryWrite($_Pointer, $DllHandle, $_Value, $_VarType) ; Write the new value at the Pointer address 
    $error = @Error ; just check if any error writing the memory
    If $error > 1 Then beep(1000,1000) ; just ring the bell if unable to write
    _MemoryClose($DllHandle) ; Close the Handle
EndFunc ;==>Write_Memory
#FUNCTION# ==============================================================
Func Read_Memory($_PID, $_Pointer, $_VarType = "int")
    ; This function will read a value in memory, allocated by the calling application ToolbarAG.exe
    Local $DllHandle = _MemoryOpen($_PID) ; Open the memory allocated by the PID from the calling application 
    Local $Data = _MemoryRead($_Pointer, $DllHandle , $_VarType) ; read value passed by the mother application
    $error = @Error ; just check if any error reading the memory
    _MemoryClose($DllHandle) ; Close the Handle
    If $error > 1 Then
        Return ""
    Else
        Return $Data
    EndIf   
EndFunc ;==>Read_Memory
#FUNCTION# ==============================================================

#include-once
#region _Memory
;=================================================================================================
; AutoIt Version:   3.1.127 (beta)
; Language:   English
; Platform:   All Windows
; Author:         Nomad
; Requirements:  These functions will only work with beta.
;=================================================================================================
; Credits:  wOuter - These functions are based on his original _Mem() functions.  But they are
;         easier to comprehend and more reliable.  These functions are in no way a direct copy
;         of his functions.  His functions only provided a foundation from which these evolved.
;=================================================================================================
;
; Functions:
;
;=================================================================================================
; Function:   _MemoryOpen($iv_Pid[, $iv_DesiredAccess[, $iv_InheritHandle]])
; Description:    Opens a process and enables all possible access rights to the process.  The
;               Process ID of the process is used to specify which process to open.  You must
;               call this function before calling _MemoryClose(), _MemoryRead(), or _MemoryWrite().
; Parameter(s):  $iv_Pid - The Process ID of the program you want to open.
;               $iv_DesiredAccess - (optional) Set to 0x1F0FFF by default, which enables all
;                              possible access rights to the process specified by the
;                              Process ID.
;               $if_InheritHandle - (optional) If this value is TRUE, all processes created by
;                              this process will inherit the access handle.  Set to TRUE
;                              (1) by default.  Set to 0 if you want it to be FALSE.
; Requirement(s):   A valid process ID.
; Return Value(s):  On Success - Returns an array containing the Dll handle and an open handle to
;                         the specified process.
;               On Failure - Returns 0
;               @Error - 0 = No error.
;                      1 = Invalid $iv_Pid.
;                      2 = Failed to open Kernel32.dll.
;                      3 = Failed to open the specified process.
; Author(s):        Nomad
; Note(s):
;=================================================================================================
Func _MemoryOpen($iv_Pid, $iv_DesiredAccess = 0x1F0FFF, $if_InheritHandle = 1)
   
    If Not ProcessExists($iv_Pid) Then
        SetError(1)
        Return 0
    EndIf
   
    Local $ah_Handle[2] = [DllOpen('kernel32.dll')]
   
    If @Error Then
        SetError(2)
        Return 0
    EndIf
   
    Local $av_OpenProcess = DllCall($ah_Handle[0], 'int', 'OpenProcess', 'int', $iv_DesiredAccess, 'int', $if_InheritHandle, 'int', $iv_Pid)
   
    If @Error Then
        DllClose($ah_Handle[0])
        SetError(3)
        Return 0
    EndIf
   
    $ah_Handle[1] = $av_OpenProcess[0]
   
    Return $ah_Handle
   
EndFunc

;=================================================================================================
; Function:   _MemoryRead($iv_Address, $ah_Handle[, $sv_Type])
; Description:    Reads the value located in the memory address specified.
; Parameter(s):  $iv_Address - The memory address you want to read from. It must be in hex
;                          format (0x00000000).
;               $ah_Handle - An array containing the Dll handle and the handle of the open
;                         process as returned by _MemoryOpen().
;               $sv_Type - (optional) The "Type" of value you intend to read.  This is set to
;                        'dword'(32bit(4byte) signed integer) by default.  See the help file
;                        for DllStructCreate for all types.
;                        An example: If you want to read a word that is 15 characters in
;                        length, you would use 'char[16]'.
; Requirement(s):   The $ah_Handle returned from _MemoryOpen.
; Return Value(s):  On Success - Returns the value located at the specified address.
;               On Failure - Returns 0
;               @Error - 0 = No error.
;                      1 = Invalid $ah_Handle.
;                      2 = $sv_Type was not a string.
;                      3 = $sv_Type is an unknown data type.
;                      4 = Failed to allocate the memory needed for the DllStructure.
;                      5 = Error allocating memory for $sv_Type.
;                      6 = Failed to read from the specified process.
; Author(s):        Nomad
; Note(s):      Values returned are in Decimal format, unless specified as a 'char' type, then
;               they are returned in ASCII format.  Also note that size ('char[size]') for all
;               'char' types should be 1 greater than the actual size.
;=================================================================================================
Func _MemoryRead($iv_Address, $ah_Handle, $sv_Type = 'dword')
   
    If Not IsArray($ah_Handle) Then
        SetError(1)
        Return 0
    EndIf
   
    Local $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
        Local $v_Value = DllStructGetData($v_Buffer, 1)
        Return $v_Value
    Else
        SetError(6)
        Return 0
    EndIf
   
EndFunc

;=================================================================================================
; Function:   _MemoryWrite($iv_Address, $ah_Handle, $v_Data[, $sv_Type])
; Description:    Writes data to the specified memory address.
; Parameter(s):  $iv_Address - The memory address you want to write to.  It must be in hex
;                          format (0x00000000).
;               $ah_Handle - An array containing the Dll handle and the handle of the open
;                         process as returned by _MemoryOpen().
;               $v_Data - The data to be written.
;               $sv_Type - (optional) The "Type" of value you intend to write.  This is set to
;                        'dword'(32bit(4byte) signed integer) by default.  See the help file
;                        for DllStructCreate for all types.
;                        An example: If you want to write a word that is 15 characters in
;                        length, you would use 'char[16]'.
; Requirement(s):   The $ah_Handle returned from _MemoryOpen.
; Return Value(s):  On Success - Returns 1
;               On Failure - Returns 0
;               @Error - 0 = No error.
;                      1 = Invalid $ah_Handle.
;                      2 = $sv_Type was not a string.
;                      3 = $sv_Type is an unknown data type.
;                      4 = Failed to allocate the memory needed for the DllStructure.
;                      5 = Error allocating memory for $sv_Type.
;                      6 = $v_Data is not in the proper format to be used with the "Type"
;                         selected for $sv_Type, or it is out of range.
;                      7 = Failed to write to the specified process.
; Author(s):        Nomad
; Note(s):      Values sent must be in Decimal format, unless specified as a 'char' type, then
;               they must be in ASCII format.  Also note that size ('char[size]') for all
;               'char' types should be 1 greater than the actual size.
;=================================================================================================
Func _MemoryWrite($iv_Address, $ah_Handle, $v_Data, $sv_Type = 'dword')
   
    If Not IsArray($ah_Handle) Then
        SetError(1)
        Return 0
    EndIf
   
    Local $v_Buffer = DllStructCreate($sv_Type)
   
    If @Error Then
        SetError(@Error + 1)
        Return 0
    Else
        DllStructSetData($v_Buffer, 1, $v_Data)
        If @Error Then
            SetError(6)
            Return 0
        EndIf
    EndIf
   
    DllCall($ah_Handle[0], 'int', 'WriteProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '')
   
    If Not @Error Then
        Return 1
    Else
        SetError(7)
        Return 0
    EndIf
   
EndFunc

;=================================================================================================
; Function:   _MemoryClose($ah_Handle)
; Description:    Closes the process handle opened by using _MemoryOpen().
; Parameter(s):  $ah_Handle - An array containing the Dll handle and the handle of the open
;                         process as returned by _MemoryOpen().
; Requirement(s):   The $ah_Handle returned from _MemoryOpen.
; Return Value(s):  On Success - Returns 1
;               On Failure - Returns 0
;               @Error - 0 = No error.
;                      1 = Invalid $ah_Handle.
;                      2 = Unable to close the process handle.
; Author(s):        Nomad
; Note(s):
;=================================================================================================
Func _MemoryClose($ah_Handle)
   
    If Not IsArray($ah_Handle) Then
        SetError(1)
        Return 0
    EndIf
   
    DllCall($ah_Handle[0], 'int', 'CloseHandle', 'int', $ah_Handle[1])
    If Not @Error Then
        DllClose($ah_Handle[0])
        Return 1
    Else
        DllClose($ah_Handle[0])
        SetError(2)
        Return 0
    EndIf
   
EndFunc

;=================================================================================================
; Function:   _MemoryPointerRead ($iv_Address, $ah_Handle, $av_Offset[, $sv_Type])
; Description:    Reads a chain of pointers and returns an array containing the destination
;               address and the data at the address.
; Parameter(s):  $iv_Address - The static memory address you want to start at. It must be in
;                          hex format (0x00000000).
;               $ah_Handle - An array containing the Dll handle and the handle of the open
;                         process as returned by _MemoryOpen().
;               $av_Offset - An array of offsets for the pointers.  Each pointer must have an
;                         offset.  If there is no offset for a pointer, enter 0 for that
;                         array dimension.
;               $sv_Type - (optional) The "Type" of data you intend to read at the destination
;                         address.  This is set to 'dword'(32bit(4byte) signed integer) by
;                         default.  See the help file for DllStructCreate for all types.
; Requirement(s):   The $ah_Handle returned from _MemoryOpen.
; Return Value(s):  On Success - Returns an array containing the destination address and the value
;                         located at the address.
;               On Failure - Returns 0
;               @Error - 0 = No error.
;                      1 = $av_Offset is not an array.
;                      2 = Invalid $ah_Handle.
;                      3 = $sv_Type is not a string.
;                      4 = $sv_Type is an unknown data type.
;                      5 = Failed to allocate the memory needed for the DllStructure.
;                      6 = Error allocating memory for $sv_Type.
;                      7 = Failed to read from the specified process.
; Author(s):        Nomad
; Note(s):      Values returned are in Decimal format, unless a 'char' type is selected.
;               Set $av_Offset like this:
;               $av_Offset[0] = NULL (not used)
;               $av_Offset[1] = Offset for pointer 1 (all offsets must be in Decimal)
;               $av_Offset[2] = Offset for pointer 2
;               etc...
;               (The number of array dimensions determines the number of pointers)
;=================================================================================================
Func _MemoryPointerRead ($iv_Address, $ah_Handle, $av_Offset, $sv_Type = 'dword')
   
    If IsArray($av_Offset) Then
        If IsArray($ah_Handle) Then
            Local $iv_PointerCount = UBound($av_Offset) - 1
        Else
            SetError(2)
            Return 0
        EndIf
    Else
        SetError(1)
        Return 0
    EndIf
   
    Local $iv_Data[2], $i
    Local $v_Buffer = DllStructCreate('dword')
   
    For $i = 0 to $iv_PointerCount
       
        If $i = $iv_PointerCount Then
            $v_Buffer = DllStructCreate($sv_Type)
            If @Error Then
                SetError(@Error + 2)
                Return 0
            EndIf
           
            $iv_Address = '0x' & hex($iv_Data[1] + $av_Offset[$i])
            DllCall($ah_Handle[0], 'int', 'ReadProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '')
            If @Error Then
                SetError(7)
                Return 0
            EndIf
           
            $iv_Data[1] = DllStructGetData($v_Buffer, 1)
           
        ElseIf $i = 0 Then
            DllCall($ah_Handle[0], 'int', 'ReadProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '')
            If @Error Then
                SetError(7)
                Return 0
            EndIf
           
            $iv_Data[1] = DllStructGetData($v_Buffer, 1)
           
        Else
            $iv_Address = '0x' & hex($iv_Data[1] + $av_Offset[$i])
            DllCall($ah_Handle[0], 'int', 'ReadProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '')
            If @Error Then
                SetError(7)
                Return 0
            EndIf
           
            $iv_Data[1] = DllStructGetData($v_Buffer, 1)
           
        EndIf
       
    Next
   
    $iv_Data[0] = $iv_Address
   
    Return $iv_Data

EndFunc

;=================================================================================================
; Function:   _MemoryPointerWrite ($iv_Address, $ah_Handle, $av_Offset, $v_Data[, $sv_Type])
; Description:    Reads a chain of pointers and writes the data to the destination address.
; Parameter(s):  $iv_Address - The static memory address you want to start at. It must be in
;                          hex format (0x00000000).
;               $ah_Handle - An array containing the Dll handle and the handle of the open
;                         process as returned by _MemoryOpen().
;               $av_Offset - An array of offsets for the pointers.  Each pointer must have an
;                         offset.  If there is no offset for a pointer, enter 0 for that
;                         array dimension.
;               $v_Data - The data to be written.
;               $sv_Type - (optional) The "Type" of data you intend to write at the destination
;                         address.  This is set to 'dword'(32bit(4byte) signed integer) by
;                         default.  See the help file for DllStructCreate for all types.
; Requirement(s):   The $ah_Handle returned from _MemoryOpen.
; Return Value(s):  On Success - Returns the destination address.
;               On Failure - Returns 0.
;               @Error - 0 = No error.
;                      1 = $av_Offset is not an array.
;                      2 = Invalid $ah_Handle.
;                      3 = Failed to read from the specified process.
;                      4 = $sv_Type is not a string.
;                      5 = $sv_Type is an unknown data type.
;                      6 = Failed to allocate the memory needed for the DllStructure.
;                      7 = Error allocating memory for $sv_Type.
;                      8 = $v_Data is not in the proper format to be used with the
;                         "Type" selected for $sv_Type, or it is out of range.
;                      9 = Failed to write to the specified process.
; Author(s):        Nomad
; Note(s):      Data written is in Decimal format, unless a 'char' type is selected.
;               Set $av_Offset like this:
;               $av_Offset[0] = NULL (not used, doesn't matter what's entered)
;               $av_Offset[1] = Offset for pointer 1 (all offsets must be in Decimal)
;               $av_Offset[2] = Offset for pointer 2
;               etc...
;               (The number of array dimensions determines the number of pointers)
;=================================================================================================
Func _MemoryPointerWrite ($iv_Address, $ah_Handle, $av_Offset, $v_Data, $sv_Type = 'dword')
   
    If IsArray($av_Offset) Then
        If IsArray($ah_Handle) Then
            Local $iv_PointerCount = UBound($av_Offset) - 1
        Else
            SetError(2)
            Return 0
        EndIf
    Else
        SetError(1)
        Return 0
    EndIf
   
    Local $iv_StructData, $i
    Local $v_Buffer = DllStructCreate('dword')

    For $i = 0 to $iv_PointerCount
        If $i = $iv_PointerCount Then
            $v_Buffer = DllStructCreate($sv_Type)
            If @Error Then
                SetError(@Error + 3)
                Return 0
            EndIf
           
            DllStructSetData($v_Buffer, 1, $v_Data)
            If @Error Then
                SetError(8)
                Return 0
            EndIf
           
            $iv_Address = '0x' & hex($iv_StructData + $av_Offset[$i])
            DllCall($ah_Handle[0], 'int', 'WriteProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '')
            If @Error Then
                SetError(9)
                Return 0
            Else
                Return $iv_Address
            EndIf
        ElseIf $i = 0 Then
            DllCall($ah_Handle[0], 'int', 'ReadProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '')
            If @Error Then
                SetError(3)
                Return 0
            EndIf
           
            $iv_StructData = DllStructGetData($v_Buffer, 1)
           
        Else
            $iv_Address = '0x' & hex($iv_StructData + $av_Offset[$i])
            DllCall($ah_Handle[0], 'int', 'ReadProcessMemory', 'int', $ah_Handle[1], 'int', $iv_Address, 'ptr', DllStructGetPtr($v_Buffer), 'int', DllStructGetSize($v_Buffer), 'int', '')
            If @Error Then
                SetError(3)
                Return 0
            EndIf
           
            $iv_StructData = DllStructGetData($v_Buffer, 1)
           
        EndIf
    Next

EndFunc
#endregion
Edited by GreenCan
2 people like this

Contributions

CheckUpdate - SelfUpdating script ------- Self updating script

Dynamic input validation ------------------- Use a Input masks can make your life easier and Validation can be as simple

MsgBox with CountDown ------------------- MsgBox with visual countdown

Display Multiline text cells in ListView ---- Example of pop-up or ToolTip for multiline text items in ListView

Presentation Manager ---------------------- Program to display and refresh different Border-less GUI's on a Display (large screen TV)

USB Drive Tools ------------------------------ Tool to help you with your USB drive management

Input Period udf ------------------------------ GUI for a period input

Excel ColorPicker ---------------------------- Color pickup tool will allow you to select a color from the standard Excel color palette

Excel Chart UDF ----------------------------- Collaboration project with water 

GetDateInString ------------------------------ Find date/time in a string using a date format notation like DD Mon YYYY hh:mm

TaskListAllDetailed --------------------------- List All Scheduled Tasks

Computer Info --------------------------------- A collection of information for helpdesk

Shared memory Demo ----------------------- Demo: Two applications communicate with each other through means of a memory share (using Nomad function, 32bit only)

Universal Date Format Conversion -------- Universal date converter from your PC local date format to any format

Disable Windows DetailsPane -------------- Disable Windows Explorer Details Pane

Oracle SQL Report Generator -------------  Oracle Report generator using SQL

SQLite Report Generator -------------------  SQLite Report generator using SQL

SQLite ListView and BLOB demo ---------- Demo: shows how binary (image) objects can be recognized natively in a database BLOB field

DSN-Less Database connection demo --- Demo: ActiveX Data Objects DSN-Less Database access

Animated animals ----------------------------- Fun: Moving animated objects

Perforated image in GUI --------------------- Fun: Perforate your image with image objects

UEZ's Perforator major update ------------- Fun: Pro version of Perforator by UEZ

Visual Crop Tool (GUI) ----------------------- Easy to use Visual Image Crop tool

Visual Image effect (GUI) -------------------- Visually apply effects on an image

 

 

 

Share this post


Link to post
Share on other sites



A nice example GreenCan :)

You do not need to compile one script if you replace the line in Example_Sharing_Memory_Var.au3

$return = Run("Sharing_Memory_Client.exe " & @AutoItPID & " " & $Pointer1 & " " & $Pointer2 & " " & $Pointer3, @ScriptDir)

with

$AutoItexePath = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "betaInstallDir");installDir for production
$ToRun = '"' & $AutoItexePath & '\AutoIt3.exe "' & ' "' & @ScriptDir & '\Sharing_Memory_Client.au3"' & ' "' & @AutoItPID &'" "' & $Pointer1 & '" "' & $Pointer2 & '" "' & $Pointer3 & '"'
Run($ToRun);(I might have overdone the quotation marks but it works.)

and then remove the condition in Sharing_memory_Client.au3 to make it exit if not compiled.


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

Hi Martin,

Thank you for the Hint. I didn't think about this.

I modified the example, so it runs as well compiled as not compiled now. I removed the if @compiled statement in the client. I also changed the path to production as I guess not everyone has the beta version (I don't :) )

If FileExists(@ScriptDir & "\" & "Sharing_Memory_Client.exe") = 1 Then
    $return = Run("Sharing_Memory_Client.exe " & @AutoItPID & " " & $Pointer1 & " " & $Pointer2 & " " & $Pointer3,  @ScriptDir) 
Else
    If FileExists(@ScriptDir & "\" & "Sharing_Memory_Client.au3") = 1 Then
        $AutoItexePath = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "InstallDir");betaInstallDir for beta 
        $ToRun = '"' & $AutoItexePath & '\AutoIt3.exe "' & ' "' & @ScriptDir & '\Sharing_Memory_Client.au3"' & ' "' & @AutoItPID &'" "' & $Pointer1 & '" "' & $Pointer2 & '" "' & $Pointer3 & '"'
        Run($ToRun) 
    Else
        MsgBox(48, "Error" , "'Sharing_Memory_Client.au3' not found" & @CR & "Both applications should be in the same folder.")
        Exit
    EndIf
EndIf

Cheers

GreenCan


Contributions

CheckUpdate - SelfUpdating script ------- Self updating script

Dynamic input validation ------------------- Use a Input masks can make your life easier and Validation can be as simple

MsgBox with CountDown ------------------- MsgBox with visual countdown

Display Multiline text cells in ListView ---- Example of pop-up or ToolTip for multiline text items in ListView

Presentation Manager ---------------------- Program to display and refresh different Border-less GUI's on a Display (large screen TV)

USB Drive Tools ------------------------------ Tool to help you with your USB drive management

Input Period udf ------------------------------ GUI for a period input

Excel ColorPicker ---------------------------- Color pickup tool will allow you to select a color from the standard Excel color palette

Excel Chart UDF ----------------------------- Collaboration project with water 

GetDateInString ------------------------------ Find date/time in a string using a date format notation like DD Mon YYYY hh:mm

TaskListAllDetailed --------------------------- List All Scheduled Tasks

Computer Info --------------------------------- A collection of information for helpdesk

Shared memory Demo ----------------------- Demo: Two applications communicate with each other through means of a memory share (using Nomad function, 32bit only)

Universal Date Format Conversion -------- Universal date converter from your PC local date format to any format

Disable Windows DetailsPane -------------- Disable Windows Explorer Details Pane

Oracle SQL Report Generator -------------  Oracle Report generator using SQL

SQLite Report Generator -------------------  SQLite Report generator using SQL

SQLite ListView and BLOB demo ---------- Demo: shows how binary (image) objects can be recognized natively in a database BLOB field

DSN-Less Database connection demo --- Demo: ActiveX Data Objects DSN-Less Database access

Animated animals ----------------------------- Fun: Moving animated objects

Perforated image in GUI --------------------- Fun: Perforate your image with image objects

UEZ's Perforator major update ------------- Fun: Pro version of Perforator by UEZ

Visual Crop Tool (GUI) ----------------------- Easy to use Visual Image Crop tool

Visual Image effect (GUI) -------------------- Visually apply effects on an image

 

 

 

Share this post


Link to post
Share on other sites

After a cursory glance, the only thing I would change is when exiting the mother process, it should wait for the child process to end after writing the exit memory value, before exiting itself. The child can't read the variable if the mother process has ended.

Share this post


Link to post
Share on other sites

@Ptrex,

Thanks

@wraithdu,

You are right. The example still works because I am testing for an exit value of 0 and when the mother exits, all pointers are released.

I just commented out the 2 EXIT commands (line 93 and 97) in the mother application. The child then sets the value to -1 which is the signal for the mother to quit.

GreenCan


Contributions

CheckUpdate - SelfUpdating script ------- Self updating script

Dynamic input validation ------------------- Use a Input masks can make your life easier and Validation can be as simple

MsgBox with CountDown ------------------- MsgBox with visual countdown

Display Multiline text cells in ListView ---- Example of pop-up or ToolTip for multiline text items in ListView

Presentation Manager ---------------------- Program to display and refresh different Border-less GUI's on a Display (large screen TV)

USB Drive Tools ------------------------------ Tool to help you with your USB drive management

Input Period udf ------------------------------ GUI for a period input

Excel ColorPicker ---------------------------- Color pickup tool will allow you to select a color from the standard Excel color palette

Excel Chart UDF ----------------------------- Collaboration project with water 

GetDateInString ------------------------------ Find date/time in a string using a date format notation like DD Mon YYYY hh:mm

TaskListAllDetailed --------------------------- List All Scheduled Tasks

Computer Info --------------------------------- A collection of information for helpdesk

Shared memory Demo ----------------------- Demo: Two applications communicate with each other through means of a memory share (using Nomad function, 32bit only)

Universal Date Format Conversion -------- Universal date converter from your PC local date format to any format

Disable Windows DetailsPane -------------- Disable Windows Explorer Details Pane

Oracle SQL Report Generator -------------  Oracle Report generator using SQL

SQLite Report Generator -------------------  SQLite Report generator using SQL

SQLite ListView and BLOB demo ---------- Demo: shows how binary (image) objects can be recognized natively in a database BLOB field

DSN-Less Database connection demo --- Demo: ActiveX Data Objects DSN-Less Database access

Animated animals ----------------------------- Fun: Moving animated objects

Perforated image in GUI --------------------- Fun: Perforate your image with image objects

UEZ's Perforator major update ------------- Fun: Pro version of Perforator by UEZ

Visual Crop Tool (GUI) ----------------------- Easy to use Visual Image Crop tool

Visual Image effect (GUI) -------------------- Visually apply effects on an image

 

 

 

Share this post


Link to post
Share on other sites

Nice work GreenCan!

Thanks for sharing.

UEZ


Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

Hiho Forum :shifty:,

I'm currently playing around with GreenCans excellent example above :x...

Can anyone tell me if I might have to worry about access problems, e.g. because of user access restriction (non-privileged / non-admin accounts) in Windows XP or Win7?

I tested it with a Guest account on my on computer, and I'll "assume" that there should be no problems because the called process is owned by the calling process :P, I would welcome any insights.

Best Regards

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

You know that nomad memory udf will not work on a 64bit OS ?

greetz from very sunny Bonn

Sundance

Edited by Sundance

Share this post


Link to post
Share on other sites

Any Tips how to make it work if compiled as x64?

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

I would appreciate if you provide a sample code of"Sharing_Memory_Client.au3" written with Ascend4nts functions.

Thanks

The folowing function is uncompatible with the above script.

Can someone help to make i work together?

Func _dbg($msg = "NotFound")
Global $Pass
$Pass += 1
$Pass = String($Pass)
$PID = String(@AutoItPID)
If $msg = "NotFound" Then
DllCall("kernel32.dll", "none", "OutputDebugString", "str", $PID & " Pass: " & $Pass)
Else
DllCall("kernel32.dll", "none", "OutputDebugString", "str", $msg)
EndIf
EndFunc   ;==>_dbg
Edited by mailro

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

For those of us who don't install AutoIt, I would change this code from "Example_Sharing_Memory_Var.au3":

If FileExists(@ScriptDir & "" & "Sharing_Memory_Client.exe") = 1 Then
    $return = Run("Sharing_Memory_Client.exe " & @AutoItPID & " " & $Pointer1 & " " & $Pointer2 & " " & $Pointer3,  @ScriptDir)
Else
    If FileExists(@ScriptDir & "" & "Sharing_Memory_Client.au3") = 1 Then
        $AutoItexePath = RegRead("HKEY_LOCAL_MACHINESOFTWAREAutoIt v3AutoIt", "InstallDir");betaInstallDir for beta
        $ToRun = '"' & $AutoItexePath & 'AutoIt3.exe "' & ' "' & @ScriptDir & 'Sharing_Memory_Client.au3"' & ' "' & @AutoItPID &'" "' & $Pointer1 & '" "' & $Pointer2 & '" "' & $Pointer3 & '"'
        Run($ToRun)
    Else
        MsgBox(48, "Error" , "'Sharing_Memory_Client.au3' not found" & @CR & "Both applications should be in the same folder.")
        Exit
    EndIf
EndIf

To this code:

If FileExists(@ScriptDir & "" & "Sharing_Memory_Client.exe") = 1 Then
    $return = Run("Sharing_Memory_Client.exe " & @AutoItPID & " " & $Pointer1 & " " & $Pointer2 & " " & $Pointer3,  @ScriptDir)
Else
    If FileExists(@ScriptDir & "" & "Sharing_Memory_Client.au3") = 1 Then
        $ToRun = @AutoItExe & ' /AutoIt3ExecuteScript "' & @ScriptDir & 'Sharing_Memory_Client.au3"' & ' "' & @AutoItPID &'" "' & $Pointer1 & '" "' & $Pointer2 & '" "' & $Pointer3 & '"'
        Run($ToRun)
    Else
        MsgBox(48, "Error" , "'Sharing_Memory_Client.au3' not found" & @CR & "Both applications should be in the same folder.")
        Exit
    EndIf
EndIf

The difference is removing:

$AutoItexePath = RegRead("HKEY_LOCAL_MACHINESOFTWAREAutoIt v3AutoIt", "InstallDir");betaInstallDir for beta
$ToRun = '"' & $AutoItexePath & 'AutoIt3.exe "' & ' "' & @ScriptDir & 'Sharing_Memory_Client.au3"' & ' "' & @AutoItPID &'" "' & $Pointer1 & '" "' & $Pointer2 & '" "' & $Pointer3 & '"'

And adding:

$ToRun = @AutoItExe & ' /AutoIt3ExecuteScript "' & @ScriptDir & 'Sharing_Memory_Client.au3"' & ' "' & @AutoItPID &'" "' & $Pointer1 & '" "' & $Pointer2 & '" "' & $Pointer3 & '"'

Cheers!

Edited by OldCoder

"Intelligence is the ability to adapt to change."                                      - Stephen Hawking                                        "...not the ability to exploit others."                                                  - OldCoder

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now