Ahja und natürlich sollte man nicht nur unbenutzte Sockets schließen, sondern bei Programmende auch
[autoit]tcpshutdown()
[/autoit]aufrufen, was letztlich alles sauber aufräumen sollte.
Ahja und natürlich sollte man nicht nur unbenutzte Sockets schließen, sondern bei Programmende auch
[autoit]tcpshutdown()
[/autoit]aufrufen, was letztlich alles sauber aufräumen sollte.
Zwei Dinge...
Server: Du schließt den Socket nicht, also kaum verwunderlich, dass dieser noch ewig rumgammelt
Client: Wozu setzt du millionenfach das $GUI_EVENT_CLOSE in deiner while Schleife? Warum setzt du Events für Controls und aktivierst den oneventmode erst danach?
Seh ich auch so. Ein kompletter Verzicht auf global deklarierte Variablen mag zwar technisch umsetzbar sein, aber das erhöht eher die Risiken die durch den Einsatz globaler Variablen entstehen würden.
Grundsätzlich ist es eher wichtig sich genau Gedanken über die Benennung und den Zweck der Variablen zu machen. Braucht man eine Variable nur in einer Funktion ist das Thema klar, lokale Variable und gut. Wird sie nur in wenigen ausgewählten Funktionen benötigt sollte man sofern der Aufwand dafür nicht zu groß ist ebenfalls lokale Variablen verwenden die jeweils weitergereicht werden. Gerade in Bezug auf GUI Elemente ist das aber in der Regel nicht praktikabel, da du so ggf. eine große Menge an Parametern weiterreichen musst. Eine Lösung wäre hier dann der Einsatz von Arrays, das würde die Übergabe vereinfachen, dafür aber die Lesbarkeit des Codes erschweren. Bei solchen Sammelarrays sollte also am besten eine gute Dokumentation im Quellcode in jeder Funktion die darauf zugreift vorliegen. Wenn die Variable hingegen in sehr vielen oder allen Funktionen benötigt wird ist es per Definition eben eine globale Variable. Hier ist dann höchste Vorsicht geboten, da je nach Programmgröße eben schwer nachvollziehbar ist wer berechtigter oder ggf. auch unberechtigter Weise, also versehentlich den Inhalt der Variable geändert hat.
Am allerwichtigsten ist aber nicht die Frage "global ja oder nein?", sondern "deklariert ja oder nein?". Eine einzige Variable die als lokale gedacht war aber nicht deklariert wurde kann mit einer gleichnamigen globalen kolidieren. Daher sollte man sich zum einen niemals auf das "Dim" Statement verlassen und natürlich auch wirklich jede Variable explizit local oder global deklarieren.
Hilfreich ist hier auch der Einsatz von
[autoit]AutoItSetOption("MustDeclareVars", 1)
[/autoit]Tjo weder im Explorer noch mit Filezilla scheint das so zu klappen. Notepad und Word funktionieren hingegen einwandfrei. Von meiner Seite wird hier eher nichts mehr kommen, hab nun lange genug damit rumgespielt. Die Frage bleibt auch wozu man sowas braucht. Normalerweise kann man die meisten Programme sehr viel besser auf anderem Wege automatisieren oder eben auf besser automatisierbare Alternativen zurückgreifen. Drag and Drop würde jedenfalls niemals zu meiner ersten Wahl zählen.
Ehm you could at least try english. I doubt that a lot of guys here understand your post. There is also an english autoit forum, perhaps you get there more support.
Call ("signIn")
[/autoit]Ähm? wie wäre es die Funktion einfach so aufzurufen:
[autoit]SignIn()
[/autoit]Das nur als kleine Anregung, nun zu deinem Anliegen:
Nun sollte er eigentlich auf den Login button klicken.Nur finde ich da keinen Namen.Ich habe nur das hier :<input class="btn-submit" src="image/ha/_login-button.gif" value="Login" style="margin-left: 5px;" type="image">
Wie kann ich Autoit dazu bewegen das er darauf klickt ?
$oForm = _IEFormGetObjByName($oIE, "ExampleForm") ; vermutlich in deinem Fall loginform oder takelogin oder was weiß ich, siehe Quellcode der Webseite
_IEFormSubmit($oForm)
; Alternativ könntest du auch auf das Bild des Buttons klicken
[/autoit][autoit][/autoit][autoit]_IEImgClick(...) ; siehe Hilfe
[/autoit][autoit][/autoit][autoit][/autoit]PS: Ich bezweifle, dass du dich durch meine ~1500 Zeilen Code durchwurschteln möchtest. Ich bin mit Kommentaren sehr "zurückhaltend"
Niemand braucht hier 1500 Zeilen Code um dein Problem nachvollziehen zu können. Ein simples lauffähiges Testscript reicht völlig (GUI mit Listview und 2-3 auswählbare Einträge, sämtlicher Code der von dir zur Ermittlung des drop (Fenster)handles und zur Ausführung der Dropsache verwendet wird.) Das ist vermutlich mit 200-300 Zeilen getan, wenn überhaupt so viel. Dazu wären dann Infos brauchbar welche Programme nicht funktionieren, wo genau im Fenster der Anwendung gedroppt werden soll/muss und was dein Debugging in solchen Fällen ergibt.
Deine Dodropfiles Funktion unterscheidet sich jedenfalls von meiner und der im englischen Forum. Woher kommt der Parameter $cID und was soll damit bewirkt werden? Soweit ich die Diskussion dort verstanden habe kann man anstatt an das Fensterhandle + Koordinaten auch an das Controlhandle droppen. Dafür braucht es aber keine Änderung der Funktion, man übergibt einfach controlgethandle anstatt wingethandle für den Parameter $wnd
Alternativ kann man auch in der Struct die Werte für px und py modifizieren um ein Drop auf eine bestimmte Stelle im Fenster anhand der Koordinaten zu erreichen. Da du die relative Mausposition im Fenster recht einfach bekommen kannst würde ich genau diesen Ansatz verwenden. Das dürfte im übrigen auch der Grund sein warum der Drop auf deine eigene Testgui nicht klappt. Standardmässig dropt die Funktion an die Stelle x=0 und y=0. Deine GUI erlaubt aber nur drops auf das input control, welches eben nicht an der Position x=0 und y=0 ist. Du könntest also nun statt dem winhandle das controlhandle an dodropfiles übergeben oder du nimmst das winhandle plus passende Koordinaten. Beides sollte zum Erfolg führen.
denn nichtmal mein eigenes kleines Testscript:
...
akzeptiert, was ich übergebe...
Hier ist denke ich keiner Hellseher. Was du nun übergibst oder auch nicht steht hier nirgendwo. Ich schlage also mal vor, dass du so langsam deine Versuche des sendenden Scriptes hier postest, denn um das geht es ja schließlich. Dann kann man das zum einen auch mal testen und zum anderen kann man sich dann auch drüber unterhalten in welchen externen Programmen es nicht und vorallem warum es gerade dort nicht funktioniert.
Ergänzend sollte man seine Variablen vielleicht auch noch etwas aussagekräftiger benennen. Ebenfalls problematisch sehe ich das hotkeyset(..) innerhalb der gui schleife, das hat da gewiss nichts verloren und ist evtl. sogar die Ursache für das seltsame Verhalten der GUI.
Also erstmal Code aufräumen und auch optisch durch Einrückungen vernünftig gestalten, dann kann man vielleicht auch den Fehler finden.
PS: Zumindestens unter meiner Autoit Version fehlt da oben im Code das Include <windowsConstants.au3>. Mag aber sein, dass das in der aktuellen Autoit Version irgendwoanders mit drin ist (ich meine sowas im changelog gelesen zu haben)
Ähm ja dafür ist das ja auch gedacht. Die externe GUI muss selbst Drops erlauben, so wie du es oben mit deinen eigenen GUI Elementen gemacht hast. Nur weil du Drops erlaubst bedeutet das ja noch lange nicht, dass andere Programme das auch tun müssen/sollen/wollen was auch immer. Sofern sie es tun musst du den Drop auf dieses Fenster eben auslösen, siehe dodropfiles().
Nochmal zur Vorgehensweise:
1. Du ermittelst bei "Maus DOWN" welches Element in deinem Listview angeklickt wurde, schaust meinetwegen in irgendeiner DB nach und hast letztlich den Pfad und Dateinamen der zu droppenden Datei.
2. Sobald "Maus UP" schaust du mit den Methoden aus meinem zweiten Link nach wie das Handle des Fensters lautet über dem sich die Maus gerade befindet.
3. Nun rufst du die Funktion dodropfiles() mit dem ermittelten Handle und der ermittelten Datei auf. Daraufhin sollte eine Dropmessage mit dem Dateipfad an das betreffende Fenster geschickt werden.
Zum Testen würde ich im übrigen Textdateien und Notepad verwenden, hier funktioniert ein Dateidrop mittels dodropfiles() auf jedenfall.
Könnte man theoretisch Abfragen, welches Fenster unter der Maus ist, und davon dann den handle ermitteln?
Kann man. z.B. so: http://www.autoitscript.com/forum/topic/11…lp/#entry789220
Schau dir hier mal die Funktion dodropfiles() an. Ich verwende das erfolgreich in einem meiner Scripte um ein Drop auf ein bestimmtes Fenster zu simulieren.
Schonmal in die Hilfe geschaut?
[autoit]guictrlcreatecontextmenu
[/autoit]Dort findest du ein fast fertiges Beispiel für das was du erreichen willst.
Hier das überarbeitete Example2:
#include <GUIConstantsEx.au3>
#include <ButtonConstants.au3>
HotKeySet("+!d", "hotkeymenu") ;Shift-Alt-d
[/autoit] [autoit][/autoit] [autoit]; *****************
; * Second sample *
; *****************
Global $hGui, $OptionsBtn, $OptionsDummy, $OptionsContext, $OptionsCommon, $OptionsFile, $msg, $HotkeyDummy, $HotkeyContext, $HotkeyTestItem
Global $OptionsExit, $HelpBtn, $HelpDummy, $HelpContext, $HelpWWW, $HelpAbout
$hGui = GUICreate("My GUI", 170, 40)
$OptionsBtn = GUICtrlCreateButton("&Options", 10, 10, 70, 20, $BS_FLAT)
[/autoit] [autoit][/autoit] [autoit]; At first create a dummy control for the options and a contextmenu for it
$OptionsDummy = GUICtrlCreateDummy()
$OptionsContext = GUICtrlCreateContextMenu($OptionsDummy)
$OptionsCommon = GUICtrlCreateMenuItem("Common", $OptionsContext)
$OptionsFile = GUICtrlCreateMenuItem("File", $OptionsContext)
GUICtrlCreateMenuItem("", $OptionsContext)
$OptionsExit = GUICtrlCreateMenuItem("Exit", $OptionsContext)
$HelpBtn = GUICtrlCreateButton("&Help", 90, 10, 70, 20, $BS_FLAT)
[/autoit] [autoit][/autoit] [autoit]; Create a dummy control and a contextmenu for the help too
$HelpDummy = GUICtrlCreateDummy()
$HelpContext = GUICtrlCreateContextMenu($HelpDummy)
$HelpWWW = GUICtrlCreateMenuItem("Website", $HelpContext)
GUICtrlCreateMenuItem("", $HelpContext)
$HelpAbout = GUICtrlCreateMenuItem("About...", $HelpContext)
$HotkeyDummy = GUICtrlCreateDummy()
$HotkeyContext = GUICtrlCreateContextMenu($HotkeyDummy)
$HotkeyTestItem = GUICtrlCreateMenuItem("Test", $HotkeyContext)
GUISetState()
[/autoit] [autoit][/autoit] [autoit]While 1
$msg = GUIGetMsg()
Switch $msg
Case $OptionsExit, $GUI_EVENT_CLOSE
ExitLoop
Case $OptionsBtn
ShowMenu($hGui, $msg, $OptionsContext)
Case $HelpBtn
ShowMenu($hGui, $msg, $HelpContext)
Case $HelpAbout
MsgBox(64, "About...", "GUICtrlGetHandle-Sample")
Case $HotkeyTestItem
MsgBox(64, "HotkeyTest", "Test")
EndSwitch
WEnd
GUIDelete()
Func hotkeymenu()
ShowMenu($hGui, -1, $HotkeyContext)
EndFunc
; Show a menu in a given GUI window which belongs to a given GUI ctrl
Func ShowMenu($hWnd, $CtrlID, $nContextID)
Local $arPos, $x, $y
Local $hMenu = GUICtrlGetHandle($nContextID)
if $CtrlID = -1 Then
$arPos = MouseGetPos()
$x = $arPos[0]
$y = $arPos[1]
Else
$arPos = ControlGetPos($hWnd, "", $CtrlID)
$x = $arPos[0]
$y = $arPos[1] + $arPos[3]
ClientToScreen($hWnd, $x, $y)
EndIf
TrackPopupMenu($hWnd, $hMenu, $x, $y)
EndFunc ;==>ShowMenu
; Convert the client (GUI) coordinates to screen (desktop) coordinates
Func ClientToScreen($hWnd, ByRef $x, ByRef $y)
Local $stPoint = DllStructCreate("int;int")
DllStructSetData($stPoint, 1, $x)
DllStructSetData($stPoint, 2, $y)
DllCall("user32.dll", "int", "ClientToScreen", "hwnd", $hWnd, "ptr", DllStructGetPtr($stPoint))
[/autoit] [autoit][/autoit] [autoit]$x = DllStructGetData($stPoint, 1)
$y = DllStructGetData($stPoint, 2)
; release Struct not really needed as it is a local
$stPoint = 0
EndFunc ;==>ClientToScreen
; Show at the given coordinates (x, y) the popup menu (hMenu) which belongs to a given GUI window (hWnd)
Func TrackPopupMenu($hWnd, $hMenu, $x, $y)
DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $x, "int", $y, "hwnd", $hWnd, "ptr", 0)
EndFunc ;==>TrackPopupMenu
Du musst dir nun nur noch einfallen lassen wie du die GUI verschwinden lässt oder erst garnicht sichtbar erstellst. Das sollte aber wohl kein sonderliches Problem sein.
Wo ist das Problem? Dein autoit code ist korrekt, wenn man mal davon absieht, dass du unvosichtig mit evtl. vorhandenen Leerzeichen im Interfacename umgehst.
Besser wäre es den Befehl so aufzubauen, dass der Interface Name mit Anführungszeichen umschlossen wird:
[autoit]
$s_schnittstellenname = "lan-verbindung 7"
Run(@ComSpec & ' /k ' & 'netsh interface show interface "' & $s_schnittstellenname & '"')
Chesstiger hat dir zudem die (vermutlich) korrekte netsh Befehlssystax zum deaktivieren des Adpaters gepostet und außerdem den Hinweis, dass du dafür Administrator Privilegien benötigst. Diese bekommst du normalerweise durch den Einsatz von
[autoit]#Requireadmin
[/autoit]Problem 1 habe ich nun gelöst, allerdings komme ich hier nicht weiter:
Hinter die variable einfach % anhängen funktioniert nicht, dann gibts nen Error.
[autoit]! SQLite.au3 Error
[/autoit]
--> Function: _SQLite_Query
--> Query: Select DISTINCT a.title, a.oid, a.size, a.disk from DB a, DB b where (a.title like b.title% and a.oid <> b.oid) And (a.disk In ('HD 1') Or b.disk In ('HD 1')) Order by a.title;
--> Error: near "and": syntax error
Du musst in diesem Fall vermutlich wie in Autoit auch eine Stringverkettung mit der Variable realisieren. Dafür gibt es in sqlite den concatenate Operator ![]()
Ich kann es gerade nicht testen, sollte aber so funktionieren:
hotkeyset
[/autoit]Hier findet sich ein etwas seltsamer Satz, der nicht wirklich Sinn ergibt und im übrigen auch in meiner englischen Hilfe (3.3.6.1) fehlt. Eventuell wurde er erst später in die englische Hilfe eingebaut. Wie dem auch sei, das hier ergibt keinen Sinn:
ZitatEs ist besser die Kleinschreibtaste zu verwenden, als russische. Die nicht mit Shift betätigte Taste ist nicht der untere Wert. Zum Beispiel: "D" ist nicht die Großschrift von "B". Der Hotkey wird nicht gesetzt werden und ein Fehler wird auftreten.
Verstehe hier das Problem nicht so recht.
Aktuell ist es so dass wir 2 Verknüpfungen auf dem Desktop liegen haben, "Citrix Start" und "Citrix Ende" diese verweißen auf eine lokale CMD Datei. Die CMD Dateien öffnen eine exe mit und es werden verschiedene Parameter mitgegeben. Nun haben wir aber das Problem das Citrix so 10 Sekunden brauch bis es wirklich disconnected und beendet ist, und die User drücken dann wieder auf Citrix Start und es gibt doppelte Sitzungen usw... Wenn ich jetzt mein Programm aufrufe wird geprüft ob Citrix gestartet oder gestoppt werden muss. Wenn es gestartet ist wird es gestoppt, und halt andersrum.
Dein eigentliches Problem ist also nur, dass dein Programm gestartet werden kann obwohl eine vorherige Instanz seine Arbeit noch nicht vollständig erledigt hat (citrix starten oder beenden). Ich habe dein Script jetzt nicht angesehen, daher kenne ich die Ursache dafür nicht. Prinzipiell gibt es aber nur zwei mögliche Ursachen. Entweder prüfst du nicht ob noch eine Instanz deines Scriptes läuft oder aber dein Script wartet nicht bis citrix wirklich beendet oder gestartet wurde bevor es sich selbst beendet.
Hier mal ein vereinfachtes Beispiel wie du ein Script gestalten könntest damit der User sieht, dass noch etwas passiert:
Aufruf: "test.exe -start" oder "test.exe -stop"
#include <Misc.au3>
if $cmdline[0] = 0 then Exit msgbox(0,"Fehler","ungültiger programmaufruf, bitte parameter -start oder -stop verwenden")
[/autoit] [autoit][/autoit] [autoit]if _Singleton(@ScriptName,1) = 0 Then
Exit msgbox(0,"Fehler","eine andere Instanz des citrix loaders läuft noch!")
EndIf
$citrixCheck = checkCitrix() ; ermittelt den Zustand von citrix, true wenn gestartet, false wenn nicht gestartet
[/autoit] [autoit][/autoit] [autoit]If $cmdline[1] = "-start" Then
If $citrixCheck = False Then
SplashTextOn("Citrix Loader","Citrix wird gestartet, bitte warten...",Default,Default,Default,Default,2+16+32)
citrixStart()
SplashOff()
Else
Exit MsgBox(0,"Fehler","Citrix läuft bereits!")
EndIf
Else
If $citrixCheck = True Then
SplashTextOn("Citrix Loader","Citrix wird gestopt, bitte warten...",Default,Default,Default,Default,2+16+32)
citrixStop()
SplashOff()
Else
Exit MsgBox(0,"Fehler","Citrix läuft doch garnicht!")
EndIf
EndIf
func checkCitrix()
return Random(0,1,1) ; reiner zufall zum testen...
EndFunc
Func citrixStart()
#cs citrix starten
diese Funktion darf erst verlassen werden wenn citrix wirklich gestartet wurde, prüfbar mit:
WinExists(...)
ProcessExists(...)
usw.
#ce
Local $randomWait = Random(10000,15000,1)
Sleep($randomWait)
EndFunc
Func citrixStop()
#cs citrix stoppen
diese Funktion darf erst verlassen werden wenn citrix wirklich gestoppt wurde, prüfbar mit:
WinExists(...)
ProcessExists(...)
usw.
#ce
Local $randomWait = Random(10000,15000,1)
Sleep($randomWait)
EndFunc
Das sollte dein Problem doch eigentlich lösen. Du könntest wie bisher zwei Verknüpfungen im Public Desktop bei der Installation erstellen. Der Anwender selbst braucht keine Admin Rechte weil die Verknüpfungen nie wieder angefasst werden.
Vielleicht wäre es sinnvoll ein Testscript zu erstellen, welches eine vergleichbare Datenbank mit einigen Beispieldatensätzen anlegt. Außerdem wäre es hilfreich wenn du genauer beschreibst was du eigentlich bezwecken willst. Grundsätzlich bist du bei Stringvergleichen die auf Teiltreffern aufbauen auch sehr eingeschränkt, da bietet es sich eher an den Stringvergleich in Autoit zu machen und reguläre Ausdrücke zu verwenden.
SQLITE bietet dir unter anderem diese Funktionen an, welche du in das Query einbauen könntest:
http://sqlite.org/lang_corefunc.html
Sofern sich deine Strings die "gleich" sein sollen nur durch das Vorhanden sein eines Bindestriches unterscheiden, so würde ich die evtl. vorhandenen Bindestriche vor dem Vergleich einfach mit replace() entfernen. Somit sollten ansonsten identische Strings auch als solche erkannt werden.