Wie tausche ich Variablen / Strings zwischen 2 Scripten aus
Da die Frage immer wieder mal gestellt wird, hab ich mal 2 Beispiele geschrieben
Beispiel 1
Hier wird vom Hauptscript ein zweites Script (EXE) gestartet und dann via StdIn / StdOut Daten ausgetauscht.
Vorteile:
Benötigt kein GUI.
Zielscript kann quasi nicht verwechselt werden (siehe Nachteile Beispiel 2)
Nachteile:
Empfänger muß ständig auf neue Daten prüfen.
Script2.exe MUSS von Script1 aus via Run gestartet werden.
Script_1.au3:
Spoiler anzeigen
#include <Constants.au3>
#include <GUIConstantsEx.au3>
Global $hPid = 0, $sStdOut = ""
[/autoit] [autoit][/autoit] [autoit]$hGui = GUICreate("Script 1", 200, 225, @DesktopWidth / 2 - 250, @DesktopHeight / 2 - 112)
$hEdit = GUICtrlCreateEdit("Script 1 Test Text", 10, 10, 180, 150)
$hButtonStart = GUICtrlCreateButton("Start Script 2", 10, 170, 85, 20)
$hButtonStop = GUICtrlCreateButton("Stop Script 2", 105, 170, 85, 20)
$hButtonSend = GUICtrlCreateButton("Send Edit to Script 2", 10, 195, 180, 20)
GUISetState()
While 1
$msg = GUIGetMsg()
Switch $msg
Case $GUI_EVENT_CLOSE
If $hPid Then ProcessClose($hPid)
Exit
Case $hButtonStart
$hPid = Run(@ScriptDir & "\Script_2.exe", @ScriptDir, @SW_SHOW, BitOR($STDIN_CHILD, $STDOUT_CHILD))
Case $hButtonStop
ProcessClose($hPid)
$hPid = 0
Case $hButtonSend
StdinWrite($hPid, GUICtrlRead($hEdit))
EndSwitch
If $hPid Then
$sStdOut = StdoutRead($hPid)
If @error Then $hPid = 0
If $sStdOut Then GUICtrlSetData($hEdit, $sStdOut)
EndIf
WEnd
Script_2.au3:
Spoiler anzeigen
#include <GUIConstantsEx.au3>
[/autoit] [autoit][/autoit] [autoit]Global $sStdIn = ""
[/autoit] [autoit][/autoit] [autoit]$hGui = GUICreate("Script 2", 200, 225, @DesktopWidth / 2 + 50, @DesktopHeight / 2 - 112)
$hEdit = GUICtrlCreateEdit("Script 2 Test Text", 10, 10, 180, 175)
$hButtonSend = GUICtrlCreateButton("Send Edit to Script 1", 10, 195, 180, 20)
GUISetState()
While 1
$msg = GUIGetMsg()
Switch $msg
Case $GUI_EVENT_CLOSE
Exit
Case $hButtonSend
ConsoleWrite(GUICtrlRead($hEdit))
EndSwitch
$sStdIn = ConsoleRead()
If $sStdIn Then GUICtrlSetData($hEdit, $sStdIn)
WEnd
Beispiel 2
Datenaustausch via SendMessage
Vorteile:
Der Empfänger muß nicht ständig auf neue Daten überprüfen.
Die Scripte können unabhängig voneinader gestartet werden.
Nachteile:
Setzt ein GUI voraus.
Das Zielscript wird über WinTitle definiert, d.h. wenn mehrere Fenster mit dem gleichen Title existieren, dann kann es zu Verwechsulngen kommen. (Also eindeutige Fentertitel wählen)
Script_1.au3:
Spoiler anzeigen
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
$hGui = GUICreate("Script 1", 200, 225, @DesktopWidth / 2 - 250, @DesktopHeight / 2 - 112)
$hEdit = GUICtrlCreateEdit("Script 1 Test Text", 10, 10, 180, 175)
$hButtonSend = GUICtrlCreateButton("Send Edit to Script 2", 10, 195, 180, 20)
GUISetState()
GUIRegisterMsg($WM_COPYDATA, '_MY_WM_COPYDATA')
[/autoit] [autoit][/autoit] [autoit]While 1
$msg = GUIGetMsg()
Switch $msg
Case $GUI_EVENT_CLOSE
Exit
Case $hButtonSend
_SendCopyDataString($hGui, WinGetHandle("Script 2"), GUICtrlRead($hEdit))
EndSwitch
WEnd
Func _SendCopyDataString($My_Hwnd, $Scite_hwnd, $sCmd) ; by Prog@ndy
Local $CmdStruct = DllStructCreate('Char[' & StringLen($sCmd) + 1 & ']')
DllStructSetData($CmdStruct, 1, $sCmd)
Local $COPYDATA = DllStructCreate('Ptr;DWord;Ptr')
DllStructSetData($COPYDATA, 1, 1)
DllStructSetData($COPYDATA, 2, StringLen($sCmd) + 1)
DllStructSetData($COPYDATA, 3, DllStructGetPtr($CmdStruct))
DllCall('User32.dll', 'None', 'SendMessage', 'HWnd', $Scite_hwnd, 'Int', $WM_COPYDATA, 'HWnd', $My_Hwnd, 'Ptr', DllStructGetPtr($COPYDATA))
EndFunc ;==>_SendCopyDataString
Func _MY_WM_COPYDATA($hWnd, $msg, $wParam, $lParam) ; by Prog@ndy
Local $Temp = ""
Local $COPYDATA = DllStructCreate('Ptr;DWord;Ptr', $lParam)
Local $COPYDATA_StringLen = DllStructGetData($COPYDATA, 2)
Local $CmdStruct = DllStructCreate('Char[' & $COPYDATA_StringLen & ']', DllStructGetData($COPYDATA, 3))
$COPYDATA_String = StringLeft(DllStructGetData($CmdStruct, 1), $COPYDATA_StringLen)
GUICtrlSetData($hEdit, $COPYDATA_String)
EndFunc ;==>_MY_WM_COPYDATA
Script_2.au3:
Spoiler anzeigen
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
$hGui = GUICreate("Script 2", 200, 225, @DesktopWidth / 2 + 50, @DesktopHeight / 2 - 112)
$hEdit = GUICtrlCreateEdit("Script 2 Test Text", 10, 10, 180, 175)
$hButtonSend = GUICtrlCreateButton("Send Edit to Script 1", 10, 195, 180, 20)
GUISetState()
GUIRegisterMsg($WM_COPYDATA, '_MY_WM_COPYDATA')
[/autoit] [autoit][/autoit] [autoit]While 1
$msg = GUIGetMsg()
Switch $msg
Case $GUI_EVENT_CLOSE
Exit
Case $hButtonSend
_SendCopyDataString($hGui, WinGetHandle("Script 1"), GUICtrlRead($hEdit))
EndSwitch
WEnd
Func _SendCopyDataString($My_Hwnd, $Scite_hwnd, $sCmd) ; by Prog@ndy
Local $CmdStruct = DllStructCreate('Char[' & StringLen($sCmd) + 1 & ']')
DllStructSetData($CmdStruct, 1, $sCmd)
Local $COPYDATA = DllStructCreate('Ptr;DWord;Ptr')
DllStructSetData($COPYDATA, 1, 1)
DllStructSetData($COPYDATA, 2, StringLen($sCmd) + 1)
DllStructSetData($COPYDATA, 3, DllStructGetPtr($CmdStruct))
DllCall('User32.dll', 'None', 'SendMessage', 'HWnd', $Scite_hwnd, 'Int', $WM_COPYDATA, 'HWnd', $My_Hwnd, 'Ptr', DllStructGetPtr($COPYDATA))
EndFunc ;==>_SendCopyDataString
Func _MY_WM_COPYDATA($hWnd, $msg, $wParam, $lParam) ; by Prog@ndy
Local $Temp = ""
Local $COPYDATA = DllStructCreate('Ptr;DWord;Ptr', $lParam)
Local $COPYDATA_StringLen = DllStructGetData($COPYDATA, 2)
Local $CmdStruct = DllStructCreate('Char[' & $COPYDATA_StringLen & ']', DllStructGetData($COPYDATA, 3))
$COPYDATA_String = StringLeft(DllStructGetData($CmdStruct, 1), $COPYDATA_StringLen)
GUICtrlSetData($hEdit, $COPYDATA_String)
EndFunc ;==>_MY_WM_COPYDATA
Eigentlich werden bei beiden Beispielen nur Strings übertragen.
Um nun tatsächlich Variablen zu senden, könnte man mit DllStructCreate ein Struct erstellen und den Pointer mit oben genannten Methoden verschicken...
Bei Bedarf kann ich auch hierfür ein Beispielscript schreiben!
Viel Erfolg
E