Sorry für die späte antwort, konnte erst jetzt wirklich nachschauen.
Hab es gerade getestet und funktioniert auf dem ersten Blick einwandfrei.
Ich danke dir vielmals für die (vorallem) schnelle Hilfe.
Mach weiter so.
Sorry für die späte antwort, konnte erst jetzt wirklich nachschauen.
Hab es gerade getestet und funktioniert auf dem ersten Blick einwandfrei.
Ich danke dir vielmals für die (vorallem) schnelle Hilfe.
Mach weiter so.
Hi zusammen,
ich brauche eure Hilfe.
Ich habe warscheinlich ein ähnliches Problem wie 5yp3r ihn hatte.
Allerdings ist es bei mir ein Key der ein Sonderzeichen im Namen beinhaltet, der zu Problemen führt.
An der JSON Rückgabe kann ich nichts ändern, an deiner UDF würde ich gerne auch nichts ändern sofern ich drumherum komme.
Ansonsten, schaut euch bitte folgendes Beispiel an:
;API Call Demo
Func _getInfo($sString)
;ändert die EndSZ in "/"
$sString = StringReplace($sString, "_", "/")
;Startet API Call
Local $strReturn
If $bDevOffline = False Then $strReturn = _APICallJSON("my-url" & $sString, $Base64Key)
If $bDevOffline = True Then $strReturn = '{"_object":"kategorieObject","block":{"kategorie":{"Play+":1,"Default":1,"Double":25,"Triple":10,"xPlay":15}}}' ;Offline Test
;Wandelt die Rückgabe in ein Objekt/Dictionary
Local $o_Object = _JSON_Parse($strReturn)
;Auslesen aller vorhandenen Typen
Local $vTmp = _JSON_Get($o_Object, "block.kategorie") ;Holt sich alle kategorie
Local $iSumme = 0 ;Soll später die Gesamtzahl beinhalten
For $i = 0 To $vTmp.Count - 1
_ConsoleLog("_getInfo() - Value (block.kategorie." & $vTmp.Keys[$i] & "): <" & _JSON_Get($o_Object, "block.kategorie."&$vTmp.Keys[$i]) & ">" & @CRLF)
$iSumme += _JSON_Get($o_Object, 'block.kategorie.'&$vTmp.Keys[$i]&'') ;Geht alle Keys durch und addiert deren Value
_ConsoleLog("_getInfo() - $iSumme: " & $iSumme & @CRLF)
Next
;Sendet Info zurück, wenn es eine gab (Fehlermeldung?)
Local $sInfo = _JSON_Get($o_Object, "info")
If $sInfo <> "" Then Return $sInfo
;Erstellt Rückgabe Array
Local $aResult[2] = [$iSumme,$strReturn]
Return $aResult
EndFunc ;==>_getInfo
Log Ausgabe:
2019-03-03 10:25:26 : 10244 - _getInfo() - Value (block.kategorie.Play+): <>
2019-03-03 10:25:26 : 10244 - _getInfo() - $iSumme: 0
2019-03-03 10:25:26 : 10244 - _getInfo() - Value (block.kategorie.Default): <1>
2019-03-03 10:25:26 : 10244 - _getInfo() - $iSumme: 1
2019-03-03 10:25:26 : 10244 - _getInfo() - Value (block.kategorie.Double): <25>
2019-03-03 10:25:26 : 10244 - _getInfo() - $iSumme: 26
2019-03-03 10:25:26 : 10244 - _getInfo() - Value (block.kategorie.Triple): <10>
2019-03-03 10:25:26 : 10244 - _getInfo() - $iSumme: 36
2019-03-03 10:25:26 : 10244 - _getInfo() - Value (block.kategorie.xPlay): <15>
2019-03-03 10:25:26 : 10244 - _getInfo() - $iSumme: 51
Alles anzeigen
Das erwartete Ergebnis sollte 52 sein.
Der erste Key (block.kategorie.Play+) wird nicht ausgewertet, bzw ausgelesen.
Könnt ihr mir bitte weiterhelfen wie ich an den Wert komme?
Das ganze muss dynamisch bleiben, da die einzelnen Keys sich ändern können.
Gewollt ist, das ich zum Schluss sämtliche Values zusammengezählt habe.
Vielen Dank schon mal.
Sorry fürs erneute Antworten, aber ich wollte nochmal kurz ein Feedback geben,
Durch das "Enablen" und "Disablen" von den einzelnen GUIs in Verbindung mit GUISwitch() hat bei mir einige merkwürdige Verhalten entfernt.
Danke nochmals euch Beiden für eure Hilfe.
Auf euch ist immer Verlass.
Thread kann geschlossen werden.
Ja verstehe, danke für die Erklärung.
[...]Wenn man schon wechselt, sollte man darauf achten, dass alle anderen Fenster versteckt oder disabled sind, da ansonsten die Events nicht verarbeitet werden.[...]
Kann es sein, das es deshalb zu diesem Verhalten kommt?
Weil die MainGUI wurde bei mir in solchen Fällen nie versteckt, oder disabled.
Hm... ok. Mir gefällt es zwar nicht, aber ich akzeptiere es einfach mal.
Anders gesagt, bleibt mir wohl eh nichts anderes übrig.
Allerdings hatte ich sogar zu Beginn den GuiGetMessage Modus temporär (nur für das Menü) drin, mit dem gleichen Problem.
Aber davon mal abgesehen, habe ich gerade eine zweite Frage, was sogar früher ein ähnliches Symptom aufrufte.
Ist das wechseln im Script zwischen GuiGetMessage/OnEvent nicht teufelszeug? Habe immer wieder gelesen das man ausschließlich in einem Modus bleiben soll.
Ironischerweise hatte ich früher in meinem Script im Hauptabschnitt immer im OnEvent gearbeitet, aber für kleine Funktionen (beispielsweise für eine User Abfrage) kurzzeitig in den GuiGetMessage Modus gewechselt, mit eigenem Loop in der Funktion. Funktionierte damals auch wunderbar, bis zudem Zeitpunkt, an dem ich gerne Hover Effekte für meine selbsterstellten Buttons haben wollte.
Um den Hover Effekt zu erzielen hatte ich vieles probiert... von eigenen Kreationen, bis hin zu verschiedenen UDFs. Derzeit nutzte ich die GUICtrl_SetOnHover UDF und bin sehr zufrieden damit. Jedoch bekam ich Probleme mit meinem OnEvent zu GuiGetMessage wechsel und die GUI frierte immer wieder ein, sobald ich einen Button betätigte, der eine GUI erstellte, die sich im GuiGetMessage Modus befand.
Da ich zu dem Zeitpunkt nicht mehr auf den getesteten Hover Effekt verzichten wollte, hatte ich in den sauren Apfel gebissen und sämtliche Stellen, die bei mir in den GuiGetMessage wechselten auf den OnEvent umgeschrieben. Seit diesem Zeitpunkt erst lief bei mir das gesamte Script im OnEvent.
Im Nachinein würde ich dann sagen, das auch bei meinem obigen Problem aus dem ersten Post, wohl die UDF zu dem Phänomen führte (aber nur solange ich GuiGetMessage/OnEvent mischte - beim reinen OnEvent bleibt meine verdutztheit ).
€dit: Jedenfalls vielen Dank für deine Hilfsbereitschaft.
Das ist mir zwar bewusst, aber das Verhalten kann ich mir dadurch leider weiterhin nicht erklären.
Ich meine... wieso funktioniert es bei über 50% der Fälle mit der zweiten Schleife?
Zudem wäre ja nur die Funktionalität meines Hauptscripts dadurch blockiert, aber die If Not WinActive($hGUI_Menu) sollte doch genauso in der zweiten Schleife funktionieren.
Was mich aber noch weiter verunsichert ist, dass sich die ChildGUI zwar erstellt, aber im Fehlerfall "nur" die Hintergrundfarbe aufbaut... sämtliche Labels die ich in der For-Schleife erstelle sind nicht sichtbar. Durch mein _ConsoleLog (was im Grunde ein ConsoleWrite ist), sehe ich aber dass die Schleife trotzdem durchlaufen wird.
Was zudem das Fass zum Überlaufen bringt (damit meine ich meinen Kopf ), ist die Tatsache, dass die MetroGUI UDF genau so damit umgeht, eine zweite Schleife produziert und für diese sogar temporär in den GUIMsg Modus wechselt. Wurde beispielsweise ein Item in dem Menü angegklickt, wechselt MetroGUI wieder zurück in den OnEvent Modus, schließt die Funktion und landet erst dann wieder im Hauptscript.
Das macht mich richtig Konfus...
Hallo zusammen,
ich brauche mal wieder eure Hilfe.
Eigentlich habe ich meinen Fehler bereits beseitigen können, aber nur durch Zufall und würde gerne verstehen warum es sich so verhält.
Ich versuche in meiner GUI mithilfe eines Buttons ein zusätzliches Menü einzublenden, welches als eine Art Overlay über meine MainGUI gelegt wird.
Eigentlich möchte ich genau das nachbauen was in der MetroGUI UDF gemacht wird.
Aus persönlichen Gründen möchte ich MetroGUI aber nicht selbst nutzen.
Um dieses Menü zu erstellen, wird in MetroGUI eine Child GUI erstellt und das mache ich ebenso.
In der Child GUI werden einige Labels erstellt, die später auf ein OnEvent reagieren sollen (derzeit aber noch nichts machen).
Derzeit stecke ich noch in einer frühen Phase fest, daher gibts auch noch keine weitere Funktion für dieses Menü.
Sobald die Funktion für das Menü gecasted wird, wird die Child GUI erstellt und anschließend verweilt mein Script in einer neuen While-Schleife.
Einmal wird das auch so in MetroGUI gemacht, zum Zweiten fand ich es sinnvoll dass damit mein Hauptscript pausiert wird.
In der zweiten Schleife wurde ständig geprüft, ob die Child GUI noch aktiv ist (und bleibt in der Schleife), oder nicht mehr aktiv ist, dann wird die Child GUI wieder gelöscht , die Funktion gibt ein Return zurück und ich lande wieder in meinem Hauptscript.
Mein Problem war folgendes:
Sobald ich den Button gedrückt habe um die Funktion für meine Child GUI aufzurufen, passierte eine von zwei Verhaltensmuster und das leider zufällig und für mich unerklärlich.
Verhaltensmuster 1:
Verhaltensmuster 2:
Jetzt würde ich gerne verstehen warum dieses Verhalten passiert, denn erklären kann ich es mir nicht.
Es war wirklich zufällig was von den zwei Möglichkeiten passierte.
Leider ist mein Script viel zu groß und Umfangreich, als das ich es hier posten könnte, aber die Funktion für die ChildGUI teile ich in abgewandelter Form.
Func GUI_MenuStart()
_ConsoleLog("---------------------------------------------------------------------------------------" & @CRLF)
_ConsoleLog("GUI_MenuStart() - Menü wird gestartet." & @CRLF)
;Erstellt Child GUI
Local $mPos = WinGetPos($hGUI)
$hGUI_Menu = GUICreate("", 200, 300, $mPos[2]-199, 85, $WS_POPUP, $WS_EX_MDICHILD, $hGUI)
GUISetBkColor(_AlterBrightness($GUIBKCOLOR_MAIN, +10), $hGUI_Menu)
;Erstellt Menüeinträge
Local $hMenuItem[UBound($aGUI_Module, $UBOUND_ROWS)+1]
Local $sLabelSpacer = 30
For $i = 3 To UBound($aGUI_Module, $UBOUND_ROWS) - 1
If $i = 1 OR $i = 2 Then ContinueLoop ;Überspringt Menüeinträge
_ConsoleLog("GUI_MenuStart() - Erstelle Menüeintrag für: " & $aGUI_Module[$i][0] & @CRLF)
Local $aStringSize = _StringSize($aGUI_Module[$i][0], 12, 400, 0, $GUI_FONT_NORMAL, 0)
If IsArray($aStringSize) = 1 Then
$hMenuItem[$i] = GUICtrlCreateLabel($aStringSize[0], ((200-$aStringSize[2])/2), $sLabelSpacer*$i-($sLabelSpacer*2), $aStringSize[2], $aStringSize[3])
GUICtrlSetFont($hMenuItem[$i], 12, 400, 0, $GUI_FONT_NORMAL, $SS_CENTER)
GUICtrlSetBkColor($hMenuItem[$i], $GUI_BKCOLOR_TRANSPARENT)
GUICtrlSetColor($hMenuItem[$i], $GUIBKCOLOR_FONT_HEADLINE)
;Registriert Maus Events
_GUICtrl_OnHoverRegister($hMenuItem[$i], "_BTN_Hover_Func", "_BTN_Hover_Func", "_BTN_PrimaryDown_Func", "_BTN_PrimaryUp_Func")
Else
ContinueLoop
EndIf
Next
;Menü wird angezeigt
GUISetState(@SW_SHOW, $hGUI_Menu)
While 1
If Not WinActive($hGUI_Menu) Then
_ConsoleLog("GUI_MenuStart() - Menü wird geschlossen, nicht mehr aktiv." & @CRLF)
_ConsoleLog("---------------------------------------------------------------------------------------" & @CRLF)
GUIDelete($hGUI_Menu)
Return True
EndIf
Sleep(10)
WEnd
Return True
EndFunc ;==>GUI_MenuStart
Alles anzeigen
Achso... meine Lösung, womit alles so Funktioniert wie gewünscht ist folgende:
Die ChildGUI habe ich Global markiert und deklariere sie vorher.
Jetzt hab ich eine Funktion zum Checken der ChildGUI erstellt, die ständig in meiner Haupt-While-Schleife zusätzlich mit aufgerufen wird und prüft ob die ChildGUI existiert, wenn ja dann wird dort genauso geprüft ob diese aktiv ist, wie zuvor in der zweiten While-Schleife. Allerdings habe ich für diese Lösung die zweite While-Schleife gelöscht und nachdem das Menü erstellt wurde, beendet sich die Funktion für das Menü direkt wieder, damit ich in meine Haupt-While-Schleife lande.
Func GUI_MenuStart()
_ConsoleLog("---------------------------------------------------------------------------------------" & @CRLF)
_ConsoleLog("GUI_MenuStart() - Menü wird gestartet." & @CRLF)
;Erstellt Child GUI
Local $mPos = WinGetPos($hGUI)
$hGUI_Menu = GUICreate("", 200, 300, $mPos[2]-199, 85, $WS_POPUP, $WS_EX_MDICHILD, $hGUI)
GUISetBkColor(_AlterBrightness($GUIBKCOLOR_MAIN, +10), $hGUI_Menu)
;Erstellt Menüeinträge
Local $hMenuItem[UBound($aGUI_Module, $UBOUND_ROWS)+1]
Local $sLabelSpacer = 30
For $i = 3 To UBound($aGUI_Module, $UBOUND_ROWS) - 1
If $i = 1 OR $i = 2 Then ContinueLoop ;Überspringt Menüeinträge
_ConsoleLog("GUI_MenuStart() - Erstelle Menüeintrag für: " & $aGUI_Module[$i][0] & @CRLF)
Local $aStringSize = _StringSize($aGUI_Module[$i][0], 12, 400, 0, $GUI_FONT_NORMAL, 0)
If IsArray($aStringSize) = 1 Then
$hMenuItem[$i] = GUICtrlCreateLabel($aStringSize[0], ((200-$aStringSize[2])/2), $sLabelSpacer*$i-($sLabelSpacer*2), $aStringSize[2], $aStringSize[3])
GUICtrlSetFont($hMenuItem[$i], 12, 400, 0, $GUI_FONT_NORMAL, $SS_CENTER)
GUICtrlSetBkColor($hMenuItem[$i], $GUI_BKCOLOR_TRANSPARENT)
GUICtrlSetColor($hMenuItem[$i], $GUIBKCOLOR_FONT_HEADLINE)
;Registriert Maus Events
_GUICtrl_OnHoverRegister($hMenuItem[$i], "_BTN_Hover_Func", "_BTN_Hover_Func", "_BTN_PrimaryDown_Func", "_BTN_PrimaryUp_Func")
Else
ContinueLoop
EndIf
Next
;Menü wird angezeigt
GUISetState(@SW_SHOW, $hGUI_Menu)
Return True
EndFunc ;==>GUI_MenuStart
Func GUI_MenuStart_Check()
If WinExists($hGUI_Menu) Then
If Not WinActive($hGUI_Menu) Then
_ConsoleLog("GUI_MenuStart_Check() - Menü wird geschlossen, ist nicht mehr aktiv." & @CRLF)
_ConsoleLog("---------------------------------------------------------------------------------------" & @CRLF)
GUIDelete($hGUI_Menu)
EndIf
EndIf
Return True
EndFunc ;==>GUI_MenuStart_Check
Alles anzeigen
PS: Sorry fast vergessen.
Ich befinde mich im OnEventMode.
Ah, ich bin gerade am googlen.
Scheint wohl an Win10 zu liegen.
Ich suche mal weiter.
Aber vielen Dank nochmal.
So wie es bei dir aussieht, genau das wollte ich erreichen.
€dit: Perfekt https://www.autoitscript.com/forum/files/fi…for-windows-10/
€dit 2: Da mit _WinAPI_DwmEnableBlurBehindWindow10() keine Hintergrundfarbe gesetzt werden kann, habe ich mit _GDIPlus_GraphicsFillRect() die gesamte GUI Hintergrundfläche "angemalt". Der genutzte Brush brauch nur einen Alpha Wert. So hab ich quasi das Viereck vom GDIPlus "über" den Blur Effekt gelegt und habe eine durchsichtige Hintergrundfarbe meiner wahl.
Hm... sehen die Beispiele bei dir so aus?
Oder sollten die anders aussehen? Ich glaube bei mir siehts nicht wie von dir gewollt aus?
Dein erstes: https://www.imagebanana.com/s/1245/6sB2cbgO.html
Dein zweites: https://www.imagebanana.com/s/1245/yQia4t71.html
Ansonsten... beim ersten Bild wäre egt schon der gewünschte Effekt (bis auf den fehlenden Blur).
Das würde ich statt rot mit meiner eigentlichen Hintergrundfarbe füllen und dann über die gesamte GUI größe ziehen.
Auf dieser Fläche sollen dann zuletzt noch meine ganzen Buttons/Labels, etc drauf.
€dit: Selbst das example von der Hilfe Seite sieht bei mir anders aus wie es wohl gewollt wäre?!:
Ah, das ist ja schon mal super.
Das wäre dann abgehakt.
Geht das auch mit dem "durchsichtigen" Hintergrund?
In meinem Beispiel oben, hätte ich gerne das rote Viereck durchsichtig, das soll später die gesamte Fläche meiner GUI einnehmen (letzendlich so, dass der Hintergrund von Windows selbst, oder worüber die GUI auch immer liegt verschwommen durchscheint).
Hallo zusammen,
ich weiß der Thread ist schon älter, würde den trotzdem gerne hochkramen.
chesstiger erstmal möchte ich mich bei dir für das Tutorial bedanken.
Ich bin gerade an meinen ersten GDIPlus+ geh versuchen dran.
Was ich schon mal umgesetzt habe ist ein eigenes Viereck mit "X" drin, das meinen bisherigen Close Button für die GUI ersetzen soll (ich nutze $WS_POPUP + $WS_SYSMENU für meine GUI).
Jetzt würde ich gerne noch weiter gehen und hoffe das ist möglich.
Ich würde gerne von meiner GUI einen transparenten Background haben, wenn es nicht zu rechenaufwändig ist am liebsten sogar mit Blur Effekt.
Aber nur auf den Hintergrund beschränkt, sämtliche andere Elemente sollten 100% sichtbar bleiben.
Also egt genau das, was Win10 auch macht.
[Blockierte Grafik: https://s1.imagebanana.com/file/181118/thb/IA6RTEDw.PNG]
Ist soetwas mit GDIPlus+ möglich?
Am liebsten ausgehend von diesem Script, das ich von oben leicht angepasst entnommen habe.
#include <GUIConstantsEx.au3>
#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <WinAPISysWin.au3>
#include <GDIPlus.au3>
Opt("GUIOnEventMode", True)
$hWnd = GUICreate("GDI+", 400, 400, -1, -1, -1, $WS_EX_LAYERED)
GUISetBkColor(0xABCDEF, $hWnd)
GUISetOnEvent(-3, OnExit)
_GDIPlus_Startup()
;$hBrushRed = _GDIPlus_BrushCreateSolid(0xFFE81123)
$hBrushRed = _GDIPlus_BrushCreateSolid(0x80E81123)
$hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)
_GDIPlus_GraphicsSetSmoothingMode($hGraphics, 2)
$hGraphicsBMP = _GDIPlus_BitmapCreateFromGraphics(400, 400, $hGraphics)
$hBuffer = _GDIPlus_ImageGetGraphicsContext($hGraphicsBMP)
;_GDIPlus_GraphicsClear($hBuffer, 0xFFFFFFFF)
_GDIPlus_GraphicsFillRect($hBuffer, 90, 90, 199, 199, $hBrushRed)
GUIRegisterMsg($WM_PAINT, OnPaint)
_WinAPI_SetLayeredWindowAttributes($hWnd, 0xABCDEF, 255)
GUISetState()
While True
Sleep(10)
WEnd
Func OnPaint($hWnd, $iMsg, $iWParam, $iLParam)
_GDIPlus_GraphicsDrawImage($hGraphics, $hGraphicsBMP, 0, 0) ;draw buffer
Return $GUI_RUNDEFMSG
EndFunc
Func OnExit()
GDIPlusFree()
Exit
EndFunc ;==>OnExit
Func GDIPlusFree()
_GDIPlus_BrushDispose($hBrushRed)
_GDIPlus_BitmapDispose($hGraphicsBMP)
_GDIPlus_GraphicsDispose($hBuffer)
_GDIPlus_GraphicsDispose($hGraphics)
_GDIPlus_Shutdown()
EndFunc ;==>GDIPlusFree
Alles anzeigen
Vielen Dank schon mal.
VG
borsTiHD
Oh cool, danke dafür.
Werde mir das mal genauer anschauen.
Nutzt du die "Console.au3" selbst? Das sieht so aus als wäre die auf eigene Bedürfnisse zugeschnitten.
Finde ich jedenfalls sehr interessant... wenn ich mehr Zeit zum experimentieren finde, werde ich die Lösung mal für mein Problem probieren.
Die Calls meiner SubThreads werde ich wohl auch nach deinem Vorbild aufrufen, das macht es vorallem übersichtlicher.
Auch vielen Dank hierfür.
-----------------------------------------------------
Für mein ursprüngliches Problem, habe ich mich erstmal dazu entschieden es nach der Idee von autoiter umzusetzen.
Ich starte direkt wenn mein Programm startet parallel einen SubThread, der ewig mitlaufen wird.
Dieser SubThread selbst startet dann meine PythonApp und dient von nun an als eine Art "Brücke" zws. meinem MainThread und der PythonApp.
( MainThread <> SubThread <> PythonApp )
Wenn ich jetzt eine Abfrage aus der PythonApp brauche, geht es wie folgt:
Das schöne daran ist, der "Handler" entscheidet bzw. weiß wer die Antwort wollte, dadurch kann ich von verschiedenen Funktionen aus Anfragen an die PythonApp schicken, ohne jedesmal meinen MainThread/GUI sperren zu lassen, bzw auf die Antwort warten zu müssen. Sobald die Antwort fertig ist, wird diese quasi direkt ausgewertet.
Vielen vielen Dank an alpines , Bitnugger und autoiter für die großartige Hilfe (wie immer ).
Vorallem lernt man durch euch auch immer eine Menge und betrachtet Problemstellungen aus ganz anderen Perspektiven.
Liebe Grüße
borsTiHD
Hm... werde ich mal probieren.
Leider wird $STDIO_INHERIT_PARENT nicht funktionieren. Mein MainThread ist eine GUI.
Die GUI wird über einen HotKey initialisert und fragt dann automatisch gewisse APIs direkt ab (jedesmal wenn der Hotkey genutzt wird).
Dazu kann der User über manche Buttons auch Funktionen ausführen, die ich auf einen SubThread auslagere.
Die SubThreads laufen meistens im hintergrund (bzw. genauer gesagt erscheint einfach keine GUI) und fragen gewisse APIs ab, damit ich in meinem MainThread/GUI nicht auf deren Antwort hätte warten müssen und damit ich mehrere gleichzeitige Abfragen laufen lassen kann.
Allerdings nutze ich auch SubThreads die mit einer eigenen GUI starten, damit ich diese GUI unäbhängig von meinem MainThread/GUI bedienen kann.
Darum hab ich mir bisher nie weitere Gedanken bzgl des "Showflags" gemacht, aber ich kann dann bestimmt auch @SW_SHOW nehmen, wenn es dafür mit Flag sauberer ist?
Bzgl $STDIN_CHILD, $STDERR_MERGED beim SubThread, könnte das vlt helfen das ein SubThread befehle an die PythonApp senden kann?
Ich kann es frühstens morgen testen.
Vielen Dank an alle schon mal.
Mein MainThread startet mit $iPythonPID = Run($sPythonAPIPath & "Main_work.exe", $sPythonAPIPath, "", $STDIN_CHILD + $STDERR_MERGED) die PythonApp.
Später startet mein MainThread einen SubThread mit $iPID = Run($sMultiThreadFile & " --au-thread """ & $sCallback & """").
- (dabei ist $sMultiThreadFile eine beim Start erstellte Kopie im lokalen "Temp-Verzeichnis" von Windows, da mein MainThread aus einem Netzwerklaufwerk gestartet wird - zur reduzierung der Last auf dem Netzwerklaufwerk und es ist auch schneller).
Anschließend übergebe ich der PID meines SubThreads ($iPID) eine Nachricht mit der PID der PythonApp ($iPythonPID).
Ab hier würde ich dann gerne vom SubThread aus versuchen die PythonApp zu steuern.
Meine PythonApp und auch der SubThread sind meiner Kenntnis nach jeweils ein Child Prozess meines MainThreads, wie du selbst sagst.
Dann versuche doch mal, die PID der PythonApp.exe als Umgebungsvariable zu speichern, wenn du sie mit der Main.exe startest, damit dein SubThread sie dann mit EnvGet auslesen kann. Wenn das nicht funktioniert, speichere sie in ein Lockfile, dass dein SubThread sie daraus auslesen kann.
Danke für die Idee. Auch interessant sowas, das werde ich mir mal generell merken.
Die PID übertrage ich an meinen SubThread bereits mit einer Nachricht (speicher ich in einer Ini-Datei zwischen).
Nur wenn ich von meinem SubThread per StdinWrite/-Read auf die PythonApp zugreifen möchte, passiert nichts.
Meiner Recherche nach funktionieren die Funktionen nur wenn die jeweilige Anwendung ein "Child Prozess" ist?!
Lagere doch einfach die Arbeit mit dieser ominösen PythonApp.exe in ein anderes Skript / eine andere Anwendung aus. Wenn sie noch nicht gestartet ist, startest du sie aus deinem Hauptskript heraus. Ansonsten stellst du eben an diese Anwendung all deine Anfragen, die du allgemein bearbeitet haben möchtest.
Auf die "PythonApp.exe" hab ich leider keinen Einfluss. Es holt sich auch Infos aus Quellen die mir unbekannt sind, kann das System also leider auch nicht nachbauen.
Derzeit starte ich diese PythonApp über mein Hauptskript. Da ich immer wieder Infos daraus abfrage bleibt die im Hintergrund einfach offen. Würde ich die jetzt kurzfristig über einen weiteren Thread starten wollen, hab ich mein ursprüngliches Problem, dass diese PythonApp auf die ich angewiesen bin zu lange braucht bis sie einsatzbereit ist. Die Daten bekomme ich dann trotzdem, aber die Laufzeit ist leider untragbar.
€dit: @autoiter Achso. Ich glaube jetzt versteh ich was du meinst.
Ich starte direkt zu Beginn meines MainThreads einen SubThread und über diesen SubThread starte ich die PythonApp.
Immer wenn ich jetzt eine Abfrage von der PythonApp brauche, nutze ich meinen SubThread... dieser hat ständig die PythonApp parat und kümmert sich um das Handling mit schreiben/lesen.
Einerseits irgendwie etwas unschön, dass ich einen weiteren SubThread ständig laufen lassen muss, aber anderseits eine für mich akzeptable Lösung.
Der SubThread dient dann nur als Kommunikationsbrücke zws. MainThread <> PythonApp.
Danke für die Idee.
Ah ok. Hab verstanden was du meinst.
Leider würde ich gerne umgehen wollen, die PythonApp.exe erneut starten zu müssen.
Wenn die bereits gestartet ist, gehen die Abfragen nahezu direkt (dauern dann etwas um die eine Sekunde).
Bisher hab ich die Abfragen von meiner Main.exe selbst durchführen lassen (per StdinWrite/-Read).
Mein Gedanke war, damit meine Main.exe durch die ganze Abfrage nicht blockiert wird (oder um 1-2 Sekunden zusätzlich verzögert wird), den ganzen Ablauf über einen SubThread zu handeln.
Zudem möchte ich auch nicht über 10 Sekunden warten bis ich die Antwort/Info von der PythonApp.exe erhalte.
€dit: Die PythonApp.exe zu editieren kommt leider auch nicht in Frage, da hab ich keinen Einfluss drauf.
So ganz kann ich noch nicht folgen.
Würde doch bedeuten mein SubThread müsste per _RunDOS("compiled.exe myparam1 > output.txt"), den Prozess "erneut" starten?
Dann hätte ich wieder das Problem, dass die Anwendung zu lange startet.
Bisher mache ich es so.
- Ich starte "Main.exe" (mein AutoIT Programm)
- Main.exe startet im Hintergrund unsichtbar "pythonApp.exe"
- Nach längerer Zeit will ein User über das AutoIt Programm Infos Abfragen
- Main.exe startet einen SubThread >> Sub.exe (auch wenn es egt die gleiche exe ist, also praktisch "Main.exe", aber für die Theorie "Sub.exe")
- Über den Prozess von Sub.exe würde ich gerne auf den bereits gestarteten aber unsichtbaren Prozess von "pythonApp.exe" zugreifen, ohne ihn neustarten zu müssen
Würde ich stattdessen über meinen SubThread erneut "pythonApp.exe" starten wollen, müsste ich leider zu lange warten, da dieses Programm über 10 Sekunden braucht bis alles bereit ist.
Oder rede ich an dir vorbei?
Hm... so ganz verstehe ich das noch nicht, wäre aber interessant.
Aber ich glaube das geht leider nicht... diese Consolen Anwendung von der ich rede, ist in Wirklichkeit ein Python Script, welches von seinem Ersteller in eine *.exe compiliert wurde.
Zumindest manuell hab ich versucht in dieses Consolen Fenster nach dem Format '| batch_command ' einen Befehl einzugeben und das Programm versucht es genau so auszuwerten.
Hi zusammen,
ich brauche erneut euren Rat und hoffe ihr könnt mir helfen.
Folgende Ausgangssituation habe ich:
Ich nutze Forking mit einer stark veränderten AuThreads UDF (sprich, ich starte mein eigenes Script (*.exe) mehrmals für unterschiedliche Tasks).
Diese Subthreads werden kurzfristig gestartet, laufen 1-5 Sekunden und sollen mir eine Info an den Mainthread liefern.
Eine dieser Info soll mir eine Consolen Anwendung eines anderen nicht von mir geschriebenen Programms liefern.
Leider braucht diese andere Consolen Anwendung lange zum Starten.
Bisher starte ich dieses Programm mit meinem MainThread zu Beginn mit und lasse es im Hintergrund laufen (PID bekannt).
Wenn ich diese Consolen Anwendung abfrage funktioniert das auch perfekt und ich erhalte meine Rückgabe.
Jetzt möchte ich gerne (aus Laufzeitgründen und zum besseren Handling) diese Abfrage auf einen SubThread abwälzen.
Sprich, die Consolen Anwendung ist ein Child Prozess meines MainThreads, starte einen SubThread meines eigenen Programms, gib dem die Info der PID der Consolen Anwendung mit, die wiederum die Abfrage an die Consolen Anwendung schickt und auslesen soll.
Gibt es hierfür Möglichkeiten?
Unterm Strich würde ich gerne StdinWrite/-Read auf Programme anwenden, die KEINE Child Prozesse sind.
Vielen Dank im Voraus.
VG
borsTiHD