Sign in to follow this  
Followers 0
Uriziel01

sending a value to another process without GUI

12 posts in this topic

#1 ·  Posted (edited)

Hi. Im wondering what is the fastest way to send value to another process (the second process dont have any GUI). Is the only way using _WinAPI_WriteProcessMemory ?? I realiese that it can be done with Register keys, hidden text file etc. etc. but all those are to slow, i need something faster. Any ideas? :) Thx for all replys.

Edited by Uriziel01

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

You could make a hidden GUI, get the other process to set values / variables via input boxes, check boxes, etc.

GUIOnEventMode / GUICtrlSetOnEvent will let you know the moment anything has changed.

Or if one process called the other you can use Stdin / Stdout

Edited by TurionAltec

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

I can't seem to get events to work on a minimized or hidden window, so I have to poll for changes. In this case I'm looking for the checkbox to be checked.

Compile secondary.au3 into an EXE, place in the same folder as main.au3

Main.au3

;Process 1
#include <GUIConstants.au3>
#include <GUIConstantsEx.au3>

#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Autoit Form1", 202, 139, 193, 125)
$Input1 = GUICtrlCreateInput("Input1", 16, 8, 161, 21)
$Input2 = GUICtrlCreateInput("Input2", 16, 40, 169, 21)
$Input3 = GUICtrlCreateInput("Input3", 16, 72, 169, 21)
$Checkbox1 = GUICtrlCreateCheckbox("Complete", 24, 104, 89, 17)
;$Button1 = GUICtrlCreateButton("Button", 8, 8, 97, 33, 0)
GUISetState(@SW_hide)
#EndRegion ### END Koda GUI section ###
;Opt("GUIOnEventMode",1) ; Enable Onevent mode
;GUICtrlSetOnEvent ( $Checkbox1, "getdata" )
;GUISetOnEvent($GUI_event_close,"getdata",$form1)
ShellExecute("secondary.exe","",@ScriptDir)

$spacefree=0
$uptime=0
$timetotransfer=0
$newdata=0
$i=0


While GUICtrlRead($Checkbox1) <> $GUI_CHECKED
;While $newdata =0
$i+=1   ;Busy work to do while waiting for other process to finish.
sleep(5)
WEnd
getdata()

Msgbox(0,"Main","Freespace: "&$spacefree&@CRLF& "Uptime: "&$uptime&@CRLF&"Time to transfer: "&$timetotransfer& @CRLF& "$i: "&$i)
Exit

Func getdata()
    If GUICtrlRead($Checkbox1) = $GUI_CHECKED Then
        $spacefree=GUICtrlread($Input1)
        $uptime=GUICtrlread($Input2)
        $timetotransfer=TimerDiff(GUICtrlRead($Input3))
        $newdata=1
    EndIf
EndFunc

Timing how long it takes

---------------------------
Main
---------------------------
Freespace: 13160.25390625

Uptime: 3 Days 21:52:10

Time to transfer: 42.4975799996927

$i: 12
---------------------------
OK   
---------------------------

---------------------------
Secondary
---------------------------
Time to send: 23.3769934446976
---------------------------
OK   
---------------------------

So it took 42ms for the transfer to take place, which IMHO is pretty fast.

If I use a visible GUI, and onevent notification, The send time is less than 5ms, and the total transfer time 24ms.

Edited by TurionAltec

Share this post


Link to post
Share on other sites

Sorry, IP.Board ate my post, and turned half of it into gibberish.

Secondary.au3

;secondary.au3
$whnd=WinGetHandle("Autoit Form1")
$spacefree=DriveSpaceFree(@ScriptDir )
$uptime=PC_UPTIME()
$timestarted=TimerInit()
ControlSettext($whnd,"","[classnn:Edit1]",$spacefree)
ControlSettext($whnd,"","[classnn:Edit2]",$uptime)
ControlSettext($whnd,"","[classnn:Edit3]",$timestarted)
Controlcommand($whnd,"","[classnn:Button1]","Check","")
;ControlSend($whnd,"","Button1","{space}")
MsgBox(0,"Secondary", "Time to send: "&TimerDiff($timestarted))

Func PC_UPTIME()
;Function from http://www.autoitscript.com/forum/index.php?showtopic=83583&st=0&p=597925&#entry597925
    Local $day = ""
    Local $type = ""
    Local $hour = 0
    Local $min = 0
    Local $sec = 0
    Local $uptime
;
    $ret = DllCall("kernel32.dll", "long", "GetTickCount")
    If IsArray($ret) Then
        $msec = StringRight("00" & Mod($ret[0], 1000), 3)
        $uptime = Int($ret[0] / 1000)
        $sec = StringRight("00" & Mod($uptime, 60), 2)
        If $uptime >= 60 Then
            $uptime = Int($uptime / 60)
            $min = StringRight("00" & Mod($uptime, 60), 2)
            If $uptime >= 60 Then
                $uptime = Int($uptime / 60)
                $hour = StringRight("00" & Mod($uptime, 24), 2)
                If $uptime >= 24 Then; convert hours to days
                    $day = Int($uptime / 24)
                    $type = ""
                    If $day > 1 Then $type = "s"
                    $type = " Day" & $type & " "
                EndIf
            EndIf
        EndIf
        Return ($day & $type & $hour & ":" & $min & ":" & $sec)
    EndIf
EndFunc  ;==>PC_UPTIME

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Here's a way of doing it abusing using stdout, adlibenable, and Assign.

Normally using Assign is a bad idea :), but if for whatever reason variables could be coming in in a different order, or the variables sent changes each time, etc.

Some other examples using Stdout sit there and WAIT for the end of the stdout string to continue. This lets process 1 continue on while waiting for process 2.

Main.au3

;main.au3
;Transfer between processes using stdout
#include <Constants.au3>
$script2=run("secondary.exe",@ScriptDir,@SW_SHOW,$STDOUT_CHILD)

$spacefree=0
$uptime=0
$timetotransfer=0
$newdata=0
$i=0
$output=""
$timestarted=0
AdlibEnable("getdata",5)
While $newdata=0
;While $newdata =0
$i+=1   ;Busy work to do while waiting for other process to finish.
sleep(5)
WEnd


Msgbox(0,"Main","Freespace: "&$spacefree&@CR& "Uptime: "&$uptime&@CR&"Time to transfer: "&$timetotransfer& @CR& "$i: "&$i&@CR)
sleep(2000)

Exit

Func getdata()
$output&= stdoutread($script2)
If StringInStr($output,@cr)<>0 Then
    $array=StringSplit($output,";")
    For $i=1 to $array[0]-1 step 2
;   msgbox(1,$array[$i],$array[$i+1])
    Assign($array[$i],$array[$i+1])
    Next
    $spacefree=Number($spacefree)
    $timetotransfer=TimerDiff(Number($timestarted))
    $newdata=1
    AdlibDisable()
    EndIf
EndFuncoÝ÷ ÚÇ¢wZ¯&®Ý«­¢+Øíͽ¹Éä¹ÔÌ(íQɹÍÈÑݸÁɽÍÍÌÕÍ¥¹ÍѽÕÐ(í
½µÁ¥±Í½¹Éä¹ÔÌ¥¹Ñ¼¸á)ͱÀ ÈÀÀÀ¤((ÀÌØíÝ¡¹õ]¥¹Ñ!¹± ÅÕ½ÐíÕѽ¥Ð½É´ÄÅÕ½Ðì¤(ÀÌØíÍÁÉõÉ¥ÙMÁÉ¡MÉ¥ÁѥȤ(ÀÌØíÕÁÑ¥µõA
}UAQ%5 ¤(ÀÌØíÑ¥µÍÑÉÑõQ¥µÉ%¹¥Ð ¤)½¹Í½±ÝÉ¥Ñ ÅÕ½ÐíÍÁÉìÅÕ½ÐìµÀìÀÌØíÍÁɵÀìÅÕ½ÐìíÕÁÑ¥µìÅÕ½ÐìµÀìÀÌØíÕÁÑ¥µµÀìÅÕ½ÐìíÑ¥µÍÑÉÑìÅÕ½ÐìµÀìÀÌØíÑ¥µÍÑÉѵÀí
H¤(()5Í   ½à À°ÅÕ½ÐíM½¹ÉäÅÕ½Ðì°ÅÕ½ÐíQ¥µÑ¼Í¹èÅÕ½ÐìµÀíQ¥µÉ¥ ÀÌØíÑ¥µÍÑÉѤ¤()Õ¹A
}UAQ%5 ¤(íչѥ½¸É½´¡ÑÑÀè¼½ÝÝܹÕѽ¥ÑÍÉ¥Áй½´½½ÉÕ´½¥¹à¹Á¡ÀýÍ¡½ÝѽÁ¥ôàÌÔà̵ÀíÍÐôÀµÀíÀôÔäÜäÈÔµÀì¹ÑÉäÔäÜäÈÔ(%1½°ÀÌØíäôÅÕ½ÐìÅÕ½Ðì(1½°ÀÌØíÑåÁôÅÕ½ÐìÅÕ½Ðì(1½°ÀÌØí¡½ÕÈôÀ(1½°ÀÌØíµ¥¸ôÀ(1½°ÀÌØíÍôÀ(1½°ÀÌØíÕÁÑ¥µ(ì(ÀÌØíÉÐô±±
±° ÅÕ½Ðí­É¹°Ìȹ±°ÅÕ½Ðì°ÅÕ½Ðí±½¹ÅÕ½Ðì°ÅÕ½ÐíÑQ¥­
½Õ¹ÐÅÕ½Ðì¤(%%ÍÉÉä ÀÌØíÉФQ¡¸(ÀÌØíµÍôMÑÉ¥¹I¥¡Ð ÅÕ½ÐìÀÀÅÕ½ÐìµÀì5½ ÀÌØíÉÑlÁt°ÄÀÀÀ¤°Ì¤(ÀÌØíÕÁÑ¥µô%¹Ð ÀÌØíÉÑlÁt¼ÄÀÀÀ¤(ÀÌØíÍôMÑÉ¥¹I¥¡Ð ÅÕ½ÐìÀÀÅÕ½ÐìµÀì5½ ÀÌØíÕÁÑ¥µ°ØÀ¤°È¤(%ÀÌØíÕÁÑ¥µÐìôØÀQ¡¸(ÀÌØíÕÁÑ¥µô%¹Ð ÀÌØíÕÁÑ¥µ¼ØÀ¤(ÀÌØíµ¥¸ôMÑÉ¥¹I¥¡Ð ÅÕ½ÐìÀÀÅÕ½ÐìµÀì5½ ÀÌØíÕÁÑ¥µ°ØÀ¤°È¤(%ÀÌØíÕÁÑ¥µÐìôØÀQ¡¸(ÀÌØíÕÁÑ¥µô%¹Ð ÀÌØíÕÁÑ¥µ¼ØÀ¤(ÀÌØí¡½ÕÈôMÑÉ¥¹I¥¡Ð ÅÕ½ÐìÀÀÅÕ½ÐìµÀì5½ ÀÌØíÕÁÑ¥µ°ÈФ°È¤(%ÀÌØíÕÁÑ¥µÐìôÈÐQ¡¸ì½¹ÙÉС½ÕÉÌѼåÌ(ÀÌØíäô%¹Ð ÀÌØíÕÁÑ¥µ¼ÈФ(ÀÌØíÑåÁôÅÕ½ÐìÅÕ½Ðì(%ÀÌØíäÐìÄQ¡¸ÀÌØíÑåÁôÅÕ½ÐíÌÅÕ½Ðì(ÀÌØíÑåÁôÅÕ½ÐìäÅÕ½ÐìµÀìÀÌØíÑåÁµÀìÅÕ½ÐìÅÕ½Ðì(¹%(¹%(¹%(IÑÕɸ ÀÌØíäµÀìÀÌØíÑåÁµÀìÀÌØí¡½ÕȵÀìÅÕ½ÐìèÅÕ½ÐìµÀìÀÌØíµ¥¸µÀìÅÕ½ÐìèÅÕ½ÐìµÀìÀÌØíͤ(¹%)¹Õ¹ìôôÐíA
}UAQ%5
Edited by TurionAltec

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

This is better.

Compile it and launch the EXE twice.

#Include <GUIConstantsEx.au3>

Opt('WinTitleMatchMode', 3)

global const $TITLE_SENDER = '#Sender'
global const $TITLE_RECEIVER = '#Reseiver'
global const $WM_COPYDATA = 0x004A

global $sMsg, $Dummy, $Flag = 0

if WinExists($TITLE_RECEIVER) then
    if WinExists($TITLE_SENDER) then
        exit
    endif
    _Sender()
else
    _Receiver()
endif

func _Sender()
    
    local $Input, $Button, $ID
    
    GUICreate($TITLE_SENDER, 400, 100)
    $Input = GUICtrlCreateinput('', 20, 20, 360, 20)
    $Button = GUICtrlCreateButton('Send', 165, 60, 70, 23)
    $Dummy = GUICtrlCreateDummy()
    GUIRegisterMsg($WM_COPYDATA, '_WM_COPYDATA')
    GUISetState()
    
    while 1
        $ID = GUIGetMsg()
        switch $ID
            case 0
                continueloop
            case $GUI_EVENT_CLOSE
                _SendData(WinGetHandle($TITLE_RECEIVER), '@exit')
                exitloop
            case $Button
                $sMsg = GUICtrlRead($Input)
                $hWnd = WinGetHandle($TITLE_RECEIVER)
                if (not @error) and ($sMsg > '') then
                    if _SendData($hWnd, $sMsg) then
                        GUICtrlSetState($Button, $GUI_DISABLE)
                    endif
                endif
            case $Dummy
                GUICtrlSetState($Button, $GUI_ENABLE)
        endswitch
    wend
    
    GUIDelete()
endfunc

func _Receiver()
    GUICreate($TITLE_RECEIVER)
    GUIRegisterMsg($WM_COPYDATA, '_WM_COPYDATA')
    
    while 1
        Sleep(10)
        if $Flag then
            if $sMsg = '@exit' then
                exitloop
            endif
            $Flag = 0
            _DoSomething($sMsg)
            _SendData(WinGetHandle($TITLE_SENDER), '')
        endif
    wend
    
    GUIDelete()
endfunc; _Receiver

func _DoSomething($sData)
    MsgBox(0, 'Message', $sData)
endfunc; _DoSomething

func _SendData($hWnd, $sData)
    
    local $tCOPYDATA, $tMsg
    
    $tMsg = DllStructCreate('char[' & StringLen($sData) + 1 & ']')
    DllStructSetData($tMsg, 1, $sData)
    $tCOPYDATA = DllStructCreate('dword;dword;ptr')
    DllStructSetData($tCOPYDATA, 2, StringLen($sData) + 1)
    DllStructSetData($tCOPYDATA, 3, DllStructGetPtr($tMsg))
    $Ret = DllCall('user32.dll', 'lparam', 'SendMessage', 'hwnd', $hWnd, 'int', $WM_COPYDATA, 'wparam', 0, 'lparam', DllStructGetPtr($tCOPYDATA))
    if (@error) or ($Ret[0] = -1) then
        return 0
    endif
    return 1
endfunc; _SendData

func _WM_COPYDATA($hWnd, $msgID, $wParam, $lParam)
    
    local $tCOPYDATA = DllStructCreate('dword;dword;ptr', $lParam)
    local $tMsg = DllStructCreate('char[' & DllStructGetData($tCOPYDATA, 2) & ']', DllStructGetData($tCOPYDATA, 3))
    
    $sMsg = DllStructGetData($tMsg, 1)
    
; For Sender    
    GUICtrlSendToDummy($Dummy)
    
; For Receiver
    $Flag = 1
    
    return 0
endfunc; _WM_COPYDATA
Edited by Yashied
1 person likes this

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

Thanks... that will be very useful !

Edited by SagePourpre

Share this post


Link to post
Share on other sites

Yashied thank you so much for your post, it will come in handy since I need to pass data between apps.

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
Sign in to follow this  
Followers 0