1. Dashboard
  2. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team
    4. Mitgliedersuche
  3. Forenregeln
  4. Forum
    1. Unerledigte Themen
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. AutoIt.de - Das deutschsprachige Forum.
  2. Mitglieder
  3. Andy

Beiträge von Andy

  • Splash Screen in Schleife

    • Andy
    • 26. Februar 2023 um 16:57
    Zitat von casi4712

    Aber wenn ich nicht im Tray bin kommen die Splashes nicht

    So, jetzt mal GAAAANZ langsam :theke:

    Die Warnhinweise (Splashes?!) erscheinen NUR DANN, wenn dein Mauscurser über dem Trayicon ist und das kleine Fenster mit den Werten angezeigt wird!

    Genau SO ist die Schleife von dir programmiert und ich gehe davon aus dass das auch so sein muss :Glaskugel:

    Oder willst du die Warnhinweise auch sehen ohne den Maushover über dem Icon?

  • Splash Screen in Schleife

    • Andy
    • 26. Februar 2023 um 02:09

    Hi,

    bei mir (Win10 AutoIt 3.3.16.1 Ryzen 1600) werden die Warnhinweise angezeigt. Ich habe alle vorkommenden Hinweise in eine Variable gepackt und zusammen in ein Splash-Fenster geschrieben. Ist jetzt nur noch eine Funktion. Da kannst du dann einfach nur noch weitere Vergleiche und den entsprechenden Text hinzufügen, der der Rest (Nachrichten und Fenstergröße anpassen) läuft dann automatisch.

    Auch hast du im Startpost im Script in Zeile 70 eine falsche Variable verglichen, hab mal alles angepasst, ansonsten funktioniert dein Script hervorragend! :thumbup:

    Ram und Prozessor lassen sich zum Testen mit Prime95 auslasten.

    AutoIt
     #include <GuiToolTip.au3>
    #include <TrayConstants.au3>
    #include <GuiToolTip.au3>
    #include <MemoryConstants.au3>
    #include <WinAPISys.au3>
    #include <GuiToolTip.au3>
    TraySetIcon("authui.dll", -0)
    
    Global $LowRam = 1                     ; GB
    Global $ChargeLow = 60
    Global $ProcLoadHi = 90
    
    Global $NewFreeRam, $NewBatState, $conDat, $NewProcLoad, $NewfltDriveFreeSpace, $aData
    Global $strDrive = "C:\", _
            $PreviousfltDriveFreeSpace = GetDriveFreeSpace($strDrive), _
                    $fltDriveLowSpace = 20               ; GB
    
    $sPreviousFreeRam = GetFreeRam()
    $sPreviousBatState = _BatteryStatus()
    $sPreviousconState = _AcCON()
    $sPreviousProcLoad = GetCPUavg()
    
    ManageTrayIcon()
    
    
    Func ManageTrayIcon()
        TraySetToolTip($sPreviousFreeRam & " GB" & " Free RAM" & @CRLF & "Aufgeladen: " & $sPreviousBatState & "%" & @CRLF & "Prozessor Auslastung :" & $sPreviousProcLoad & " %" & @CRLF & $sPreviousconState & @CRLF & "SytemDrive free on '" & $strDrive & "' : " & $PreviousfltDriveFreeSpace & " GB")
    
        While True
            $a = WinList("[CLASS:tooltips_class32]")
            For $i = 1 To UBound($a) - 1
    
                If WinGetTitle($a[$i][1]) = $sPreviousFreeRam Then
                    $NewfltDriveFreeSpace = GetDriveFreeSpace($strDrive)
                    $NewFreeRam = GetFreeRam()
                    $NewBatState = _BatteryStatus()
                    $NewConState = _AcCON()
                    $NewProcLoad = GetCPUavg()
                    $NewTitle = "Health Status"
    
                    If $NewFreeRam <> $sPreviousFreeRam Then
                        ConsoleWrite(WinGetTitle($a[$i][1]) & @CRLF&@crlf)
    
                        TraySetToolTip($NewFreeRam & " GB" & " Free RAM" & @CRLF & "Aufgeladen: " & $NewBatState & "%" & @CRLF & "Prozessor Auslastung :" & $NewProcLoad & " %" & @CRLF & $NewConState & @CRLF & "SytemDrive free on '" & $strDrive & "' : " & $NewfltDriveFreeSpace & " GB")
                        _checks()
    
                        WinSetTitle($a[$i][1], "", $NewFreeRam)
                        ControlSetText($a[$i][1], "", "", $NewFreeRam)
                        _GUIToolTip_Update($a[$i][1])
                        $sPreviousFreeRam = $NewFreeRam
                    EndIf
    
                EndIf
            Next
            ; Sleep(10)
        WEnd
    
    EndFunc                                      ;==>ManageTrayIcon
    
    
    
    Func _checks()
    
        $warntext = ""                           ;es gibt keine warnung(en)
        ;oder doch?!
        ;RAM LEVEL
        If ($NewFreeRam <= $LowRam) Then
            $warntext &= "RAM wird knapp" & @CRLF
        EndIf
    
        ;SPACE Level
        If $NewfltDriveFreeSpace < $fltDriveLowSpace Then
            $warntext &= "Speicherplatz auf dem SystemDrive wird knapp" & @CRLF
        EndIf
    
        ;Charge Level
        If $NewBatState <= $ChargeLow And ($conDat = 0)  Then
            $warntext &= "Batterie wird knapp, bitte laden!!!" & @CRLF
        EndIf
    
        ;Last Level
        If $NewProcLoad > $ProcLoadHi  Then
            $warntext &= "Sehr hohe Prozessor Auslastung!!!" & @CRLF
        EndIf
    
        If $warntext <> "" Then
            StringReplace($warntext, @CRLF, @CRLF) ;gibt in @extended die Anzahl der Zeilen zurück
            SplashTextOn("Splash", $warntext, 450, 15+30 * @extended, 1400, 1000, 1, "Verdana",12)
            Sleep(5000)
            SplashOff()
        EndIf
    
    EndFunc                                      ;==>_checks
    
    
    Func _BatteryStatus()
        $aData = _WinAPI_GetSystemPowerStatus()  ; Array mit Batterie Werten einlesen
        $ChargeDat = $aData[2]
        Return $ChargeDat
    EndFunc                                      ;==>_BatteryStatus
    
    
    Func _AcCON()
        $bData = _WinAPI_GetSystemPowerStatus()  ; Array mit Batterie Werten einlesen
        $conDat = $aData[0]
        If $conDat = 0 Then
            $ConDatR = "Kein Netzteil"
        Else
            $ConDatR = "Netzteil angeschlossen"
        EndIf
        Return $ConDatR
    EndFunc                                      ;==>_AcCON
    
    
    Func GetFreeRam()                            ; verfügbarern RAM ermitteln
        $aMemStats = MemGetStats()
        Return Round($aMemStats[$MEM_AVAILPHYSRAM] / 1024 / 1024, 2)
    EndFunc                                      ;==>GetFreeRam
    
    Func GetDriveFreeSpace($strDrive)
        Return Round((DriveSpaceFree($strDrive) / 1024), 1)
    EndFunc                                      ;==>GetDriveFreeSpace
    
    
    Func GetCPUavg()
        Local $objWMIService, $objProcessList, $objProcess, $iLoad
        $iLoad = 0
        $objWMIService = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
        $objProcessList = $objWMIService.ExecQuery("SELECT * FROM Win32_Processor")
        For $objProcess In $objProcessList
            $iLoad = $iLoad + $objProcess.LoadPercentage
        Next
        Return $iLoad
    EndFunc                                      ;==>GetCPUavg
    Alles anzeigen
    Zitat von SOLVE-SMART

    Allerdings ist deine While Schleife nicht gerade CPU freundlich 😔 . Du solltest bei $a = WinList("[CLASS:tooltips_class32]") darauf prüfen, ob du überhaupt ein Array zurück bekommst und falls nicht irgendetwas tun (aus der Schleife springen etc.).

    Nein. Wenn $a kein Array ist, dann gibts auch kein Ubound und die Schleife endet.

    Zitat von SOLVE-SMART

    Denn ansonsten läuft dein Skript ohne Auswertung (von RAM, Batterie etc.) einfach weiter und dann bekommst du auch kein Splash Text angezeigt.

    Das ist doch Sinn und Zweck! Nur wenn das TrayFenster sichtbar ist, wird der Splashtext angezeigt!

  • FTP, SFTP + SSH Probleme mit login oder 0Byte-Dateien

    • Andy
    • 18. Februar 2023 um 16:27

    Hi,

    für "richtiges" SFTP (zugriff über SSH) würde ich an deiner Stelle erstmal abklären, ob der Provider überhaupt Zugriff per SSH zulässt!

    Viele FTP-Hoster bieten das erst im erweiterten Modus kostenpflichtig an.

    Weiterhin benötigst du dafür auch SFTP in AutoIt, du benutzt aber die "Standard" FTP-Funktionen. Es gibt eine SFTP-UDF.

    Ich würde zuerst per CMD als Administrator versuchen per SFTP-Befehl eine Verbindung mit dem Host herzustellen, wenn das klappt, versuche die SFTP-UDF.

    Ansonsten leg mal einen Testuser auf deinem FTP-Account mit einer Beispieldatei zum Download an und stelle hier die Login-Daten zur Verfügung.

  • Beispiele, Gedanken und Tipps bei der Nutzung von INI-Dateien

    • Andy
    • 17. Februar 2023 um 12:06
    Zitat von SOLVE-SMART

    Es gibt so viele Adaptionen des Agile/Scrum-Manifests, dass es unweigerlich zu Problemen bei dem einen oder anderen Team kommen muss.

    Du weißt ja, wie man TEAM definiert?! Tu´s Ein Anderer Mal!

    Zitat von SOLVE-SMART

    Dies ist absolut hilfreich für INI-Unerfahrene

    Ich hatte, auch hier im Forum, schon reichlich Scripte gesehen, bei denen INI-Dateien (falsch, die AutoIt´schen INI-Funktionen) missbraucht wurden, weil die Scripter schlicht nicht in der Lage sind/waren einfachste Textdateien zu bearbeiten bzw. die String-Bearbeitungsfunktionen zu benutzen.

    Da werden/wurden dann die INI-Funktionen als FileWrite() bzw. FileRead()-Ersatz genutzt. Mir dreht sich da der Magen um...aber wenn es funktioniert... :saint:

  • Anzeige langer Bindestrich in Edit

    • Andy
    • 17. Februar 2023 um 11:12

    Ja, pack die letzte Zeile und auch den restlichen Text der notifications einfach in Variablen:

    $Notification_Text=$Fileversion & @crlf & $Vendor & @crlf & $Model & blablub

    AutoIt
    #include <AutoItConstants.au3>
    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    
    
    
    
    #Region ### START Koda GUI section ### Form=
    $Form1_1 = GUICreate("Form1", 616, 300, 610, 151)
    $Edit1 = GUICtrlCreateEdit("", 40, 32, 553, 250, $ES_READONLY)
    
    GUICtrlSetData(-1, "")
    GUICtrlSetFont(-1, 12, 800, 0, "Arial")
    GUISetState()
    
    DllCall("user32.dll", "int", "HideCaret", "int", 0)
    
    $Label1 = GUICtrlCreateLabel("Im Eingabe Feld sollte ein Balken kreiseln...", 40, 8, 208, 17)
    
    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###
    
    Global $i = 0, $n
    
    Global $bExitLoop = False               ; Abbruchbedingung damit die While Wend schleife in _Balken beendet werden kann
    
    Global $hint_text = "please be patient until preparations are done... "
    
    
    Global $Notifications = "Fileversion: bla" & @CRLF & "Vendor: blub" & @CRLF & "Model: tralala" & @CRLF & "Device: hoppsassa " & @CRLF & @CRLF
    
    ;_Balken()
    
    Opt("GUIOnEventMode", 1) ;für das Beispiel
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit", $Form1_1)
    
    
    While 1
    ;~         $nMsg = GUIGetMsg()
    ;~         Switch $nMsg
    ;~             Case $GUI_EVENT_CLOSE
    ;~                 Exit
    ;~         EndSwitch
    
        _blablub()
        ;programmablauf
        For $r = 1 To 5
            ConsoleWrite("Programmablauf....Schritt: " & $r & @CRLF)
            Sleep(500)
        Next
    
    WEnd
    
    Func _Balken()
    ;~ ### Auflistung der Zeichencodes für $n ###
    ;~ "|" ;124 Unicode = 02502
    ;~ "/" ;47 Unicode = 02571
    ;~ "-" ;45, long 151 Unicode = 02500
    ;~ "\" ;92 Unicode = 02572
    ;~ ### END Liste ###
    
        $i = $i + 1
    
        Switch $i
            Case $i = 1
                $n = 0x2502
            Case $i = 2
                $n = 0x2571
            Case $i = 3
                $n = 0x2500
            Case $i = 4
                $n = 0x2572
            Case $i > 4
                $i = 1
    
        EndSwitch
    
        GUICtrlSetData($Edit1, $Notifications & @CRLF & $hint_text & ChrW($n))
    
    
    EndFunc                                 ;==>_Balken
    
    
    
    Func _blablub()
        ConsoleWrite("innerhalb _blablub" & @CRLF)
        ;bla=run(blub....)
    
        $i = 0                              ;globaler Zähler
        AdlibRegister("_Balken", 300)
    
        ;auswertung
        Sleep(3000)                         ;hier läuft dein Code, alle 300ms wird _Balken aufgerufen
        ;
    
        AdlibUnRegister("_Balken")
        GUICtrlSetData($Edit1, $Notifications & @CRLF & "Preparations DONE!")
        Sleep(1000)
    
    
        ConsoleWrite("Ende _blablub" & @CRLF)
    
    EndFunc                                 ;==>_blablub
    
    
    
    Func _Exit()
        Exit
    EndFunc                                 ;==>_Exit
    Alles anzeigen

    Wenn du weitere Infos nacheinander anzeigen willst, dann musst du nur die Variable $Notifications entsprechend erweitern mit zusätzlichem Text

  • Beispiele, Gedanken und Tipps bei der Nutzung von INI-Dateien

    • Andy
    • 17. Februar 2023 um 09:58

    Ich nutze INI´s u.a. um in Programmen die komplette Lokalisierung einzustellen, ohne dafür den Programmcode ändern zu müssen.

    Dabei gibt es in der INI u.a. Abschnitte, welche die komplette Beschriftung der Buttons, Menüs, Labels, Hilfetexte usw. enthalten.

    Die Sprachauswahl erfolgt über das Traymenü des Programms, welches sich (ohne Programmneustart) aktualisiert, sobald es per Rechtsklick aufgerufen wird.

    Wir setzen im Unternehmen in der Produktion auch Leiharbeiter ein, die dazu auch noch oft als "Springer" an den verschiedensten Arbeitsplätzen aktiv sind. Diese Mitarbeiter kommen aus allen möglichen Ländern und haben entsprechend ihre eigene (Mutter-)Sprache. Viele sprechen deutsch, bei den Fachbegriffen ist es dann aber schwierig.

    Meine Erfahrung hat gezeigt, dass es bei der Einarbeitung wesentlich einfacher ist, dem Mitarbeiter in seiner Muttersprache einen Vorgang/Begriff deutlich zu machen.

    Um eine "neue" Sprache in der INI anzulegen, wird der deutschsprachige Bereich der Lokalisierung kopiert und in die neue Sprache übersetzt. Sobald die INI gespeichert wurde, ist die neue "Sprache" auf allen Rechnern im Netz ohne Programmneustart per Rechtsklick im Tray verfügbar.

    Dieses Verfahren setze ich nicht nur in AutoIt ein, sondern auch in VBA. Da VBA so etwas wie #include nicht kennt, benutze ich Textdateien in verschiedensten Bereichen.

    Der mMn. positivste Nebeneffekt dabei ist, dass man sich als Programmierer Gedanken macht, warum und ob bestimmte Programminteraktionen überhaupt nötig sind und wie man diese dann eliminieren kann. Das führt zu WESENTLICH geringerer Fehlerquote und einem schnelleren Arbeitsablauf.

    Das fließt natürlich auch in meine Neuprogrammierung ein, was seitens externer Programmierer, die bei uns ab und zu reinschauen (und sich anfangs über meine, als "Nebenbeiprogrammierer" benutzte "oldschool"-Programmierung lustig machten), schon zu reichlich Überraschungen gesorgt hat.

    Mich hatte einmal der Geschäftsführer einer Branchensoftware in Begleitung seiner TOP 5 Programmierer gefragt, wieso ich (mittels AutoIt) einige neue Buttons in SEINE Software eingefügt hatte.

    Daraufhin fragte ich ihn, welcher seiner Mitarbeite JEMALS mit SEINER Software konstruktiv gearbeitet hatte! Unverständnis pur^^. Daraufhin hatte ich in SEINER Software demonstriert, dass es 19 (neunzehn) Interaktionen, d.h. Tastatureingaben/Mausklicks bedarf, um den aktuell bearbeiteten Vorgang als Begleitpapier auf dem Drucker auszudrucken. Das was jeder unserer 12 Mitarbeiter in diesem Bereich ca. 20x bis 30x am Tag ausführen muss. Benötigte Zeit dafür (je nach Server/Datenbank/Netzwerklast) 60-80 Sekunden. Stattdessen nur EIN Klick auf den "neuen" Button in der Buttonleiste, und 20 Sekunden später liegt das Papier im Drucker...

    Einsparung pro Jahr: 0,5 Stunden pro Mitarbeiter pro Tag mal 12 Mitarbeiter mal 200 Arbeitstage im Jahr sind 1200 Stunden aka 30 Mann-Wochen pro Jahr! Das ist fast ein kompletter Mitarbeiter, dessen Ressourcen freigeschaufelt werden konnten, so dass er "wichtige" Aufgaben erledigen kann!

    Daraufhin meine Frage an die anwesenden "Profis": Wieso muss ich als Anwender mir Gedanken über die Optimierung bzw. den Ablauf einer Software machen und warum wird das nicht von vornherein von den Programmierern erledigt?!

    Statt sich weltweit auf SCRUM-Events rumzutreiben und sich mit "agiler" Softwareentwicklung selbstzubeweihräuchern, sollten sich Programmierer doch eigentlich (was einer der Grundsätze der Agilität ist!) um die Kundenwünsche/anforderungen und deren unkomplizierte Umsetzung als Ziel einer Softwareentwicklung kümmern?!

    Etliche Vorgänge könn(t)en durch einfachste Mittel verbessert werden, gut gemachte INI-Dateien sind die Grundlage für gute Programme mit unterschiedlichsten, ggf. sogar vom Anwender steuerbaren, Konfigurationen.

    Und zum Thema INI sei "oldschool" (heutzutage fliegt ja alles in eine Datenbank). Wenn mein Programm nicht per se schon eine Datenbankanwendung ist/hat, dann sollte man für einige Handvoll Parameter nicht unbedingt eine anlegen....

    Zitat von SOLVE-SMART

    Nutzer, der Anwendung (wie Dritte, Außenstehende (Stakeholder bspw.)), kennen sich mit dem Programm und dessen Code nicht aus, wollen jedoch dennoch etwas am Programm beeinflussen/ändern.

    Dies wäre eine Verwendung von Konfigurationsdateien, wie einer INI.
    Eine weitere Verwendung ist ein Deployment der Anwendung auf verschiedene Server/Maschinen mit verschiedenen Konfigurationen.

    THIS!

  • [GDI+] Maussteuerung UDF

    • Andy
    • 17. Februar 2023 um 07:52
    Zitat von Mars

    Ich habe mich dafür entschieden $Transform.einstellung, oder $Transform.information zu verwenden anstatt jede einzelne Sache in eine Funktion zu wrappen. Es ist meines Erachtens nach dumm 10 Funktionen zu schreiben, wenn man die Werte sowieso direkt setzen kann. Wenn man wissen will was alles einstellbar ist muss man eben in _GDIPlus_TransformCreate nachlesen was es alles gibt und was es alles macht.

    Genau so hatte ich mir das vorgestellt. So kann man auch, je nach individueller Anforderung, eigene $Transform.-Parameter/Variablen erzeugen, die dann im $Transform-"Namespace" liegen. :klatschen:

  • Anzeige langer Bindestrich in Edit

    • Andy
    • 16. Februar 2023 um 14:59
    Zitat von hipfzwirgel

    Ich hatte keine Ahnung, dass das nur mit den Hex-Zahlen geht. Ich probierte es mit den DEZ zahlen und da kam nur Murks.

    Hexadezimal und Dezimal oder auch Binär sind nur unterschiedliche Darstellungsformen für ein- und dieselbe Zahl!

    Ob du nun $n=0x2571 schreibst oder $n=9585 ist unerheblich! Leider unterstützt AutoIt nicht nativ das Binärformat, sonst könnte man diese Zahl auch als 0b10010101110001 schreiben.

    Zitat von hipfzwirgel

    In meiner Funktion Ftsstat(), würde ich gerne den Satz
    "GUICtrlSetData($Edit1, "Please be patient until preparations are done...!" & @CRLF & @CRLF, 1)"
    gegen Eintrag mit dem drehenden Balken austauschen.

    Wie gehe ich da am besten vor?

    So?

    AutoIt
    #include <AutoItConstants.au3>
    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    
    
    
    
    #Region ### START Koda GUI section ### Form=
    $Form1_1 = GUICreate("Form1", 616, 144, 610, 151)
    $Edit1 = GUICtrlCreateEdit("", 40, 32, 553, 50, $ES_READONLY)
    
    GUICtrlSetData(-1, "")
    GUICtrlSetFont(-1, 12, 800, 0, "Arial")
    GUISetState()
    
    DllCall("user32.dll", "int", "HideCaret", "int", 0)
    
    $Label1 = GUICtrlCreateLabel("Im Eingabe Feld sollte ein Balken kreiseln...", 40, 8, 208, 17)
    
    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###
    
    Global $i = 0,$n
    
    Global $bExitLoop = False ; Abbruchbedingung damit die While Wend schleife in _Balken beendet werden kann
    
    _Balken()
    
    While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
            Case $GUI_EVENT_CLOSE
                Exit
        EndSwitch
    
        _blablub()
        ;programmablauf
        for $r=1 to 5
            consolewrite("Programmablauf....Schritt: "&$r&@crlf)
            sleep(500)
        Next
    
    WEnd
    
    Func _Balken()
    ;~ ### Auflistung der Zeichencodes für $n ###
    ;~ "|" ;124 Unicode = 02502
    ;~ "/" ;47 Unicode = 02571
    ;~ "-" ;45, long 151 Unicode = 02500
    ;~ "\" ;92 Unicode = 02572
    ;~ ### END Liste ###
    
            $i = $i + 1
    
            Switch $i
                Case $i = 1
                    $n = 0x2502
                Case $i = 2
                    $n = 0x2571
                Case $i = 3
                    $n = 0x2500
                Case $i = 4
                    $n = 0x2572
                Case $i > 4
                    $i = 1
    
            EndSwitch
    
            GUICtrlSetData($Edit1, "please be patient until preparations are done... " & Chrw($n))
    
    
    EndFunc   ;==>_Balken
    
    
    
    func _blablub()
        consolewrite("innerhalb _blablub"&@crlf)
        ;bla=run(blub....)
    
        $i=0  ;globaler Zähler
        Adlibregister("_Balken",300)
    
        ;auswertung
        Sleep(3000) ;hier läuft dein Code, alle 300ms wird _Balken aufgerufen
        ;
    
        Adlibunregister("_Balken")
        GUICtrlSetData($Edit1, "DONE!")
        sleep(1000)
    
    
        consolewrite("Ende _blablub"&@crlf)
    
    endfunc
    Alles anzeigen
  • [GDI+] Maussteuerung UDF

    • Andy
    • 16. Februar 2023 um 11:23

    Sehr schön!

    Ich würde aber noch, innerhalb von $Transform, sämtliche Ergebnisse der Funktion _WinAPI_Mouse_Event() und/oder GUIGetCursorInfo() dem User zur Verfügung stellen.

    Dann stehen sämtliche mausspezifischen Events bzw. deren Ergebnisse, in einer Variablen ($Transform)

  • 3D mit GDI+ (A3D.au3)

    • Andy
    • 31. Januar 2023 um 15:36
    Zitat von Mars

    aber ich will erstmal schauen was man ohne diese Hilfsmittel rausholen kann.

    Hatte ich oben ja bereits beschrieben....gesetzt den Fall, du optimierst die Schleifen auf die Hälfte der Zeit, das GDI-Gedöns beschleunigst du nicht. Da werden dann aus 4 FPS wegen mir 8 FPS...?!

    Allerdings ist JEDE Optimierung im noch so langsamen Code eine Verbesserung in der Ablaufgeschwindigkeit, und schlägt somit voll auch bei einer ggf. compilierten Variante durch!

    Wenn du deinen Code "schnell" machst, dann ist auch das Programm "schnell", SO zum Beispiel...

    Zitat von Mars

    Ein paar inner loops sind doof gelöst weil dort eigentlich nur der Mittelpunkt berechnet wird (z.B. in EndEscene -> Mittelpunkte berechnen & Sortieren), das kann man doppelt so schnell anderweitig lösen, oder 5x so schnell approximativ^^

    ...was aber (im Bezug auf AutoIt! )den Kohl auch nicht wirklich fett macht^^ :D

    Zitat von Mars

    Und DANN baue ich einen "richtigen" Kugelgenerator (mit GUI und ganz vielen Slidern, sodass man nicht mehr von Hand im Code arbeiten muss wenn man seine Kugel designen will).

    Mach das doch mal zuerst! Ich vermute, auf dem Weg dahin findet sich die eine oder andere Verbesserung ganz automatisch ein, weiterhin findet sich bestimmt jemand (sic), der für die Berechnungen hochperformanten SSE/AVX-Code (dafür gibts in C(++) die intrinsics(!) ) basteln könnte....ich mein ja nur.... :Glaskugel::rofl:

  • _ScreenCapture_Capture (Variable werden nicht angenommen)

    • Andy
    • 31. Januar 2023 um 11:40
    Zitat von Silvermoon1

    verweigert Autoit die Aufgabe ohne Meldung.

    Du kannst nach der _ScreenCapture_Capture()- Zeile auf @error prüfen, um den Grund zu erfahren.

    Die Fehler sind in der Help-Datei nicht beschrieben, erschließen sich aber mit Blick in die Funktion(en). In Scite den Cursor auf den Funktionsnamen und dann CTRL-J springt in diese Funktion.

    Neben den von @Musashi und Moombas beschriebenen Syntaxfehlern ist darauf zu achten, dass in dem ausgewählten Verzeichnis Schreibrechte bestehen!

  • 3D mit GDI+ (A3D.au3)

    • Andy
    • 31. Januar 2023 um 11:17

    Zunächst einmal Mars....sehr schön!

    Wieder ein Mitglied im Bereich "Brotlose Kunst" ( :theke: für die Insider 8o )

    Zitat von UEZ

    GDI+ wird leider das Speed Limit bleiben...

    Das ist sicher richtig.... aber:

    Wie so oft, sind die Berechnungen innerhalb der Schleifen der Geschwindigkeitstechnische "Supergau" bei AutoIt.

    Profiling des Scriptes hat bei mir (4 FPS) ergeben:

    - In der While-Schleife liegen die Zeiten der Zeilen bis zu Draw($Sphere) bei je 1ms, also (zunächst) unerheblich.

    - Draw($Sphere) bzw. die eigentliche Funktion __A3D_GeometryDraw() dauert 150ms, davon ca. 30ms in der ersten For/Next, bei der ausschließlich bissl addiert und subtrahiert wird.

    Die anderen 120ms werden in der zweiten For/Next "verbraten" in der, man mag es kaum glauben, auch nur bissl addiert wird. In der Summe mit den kaskadierenden OR´s je CASE ist das für einen Interpreter der schon angesprochene Supergau...

    - In der Funktion _A3D_EndScene() dauert die erste verschachtelte For/Next 85ms, bei der ausschließlich bissl addiert und dividiert wird.

    In der zweiten For/Next (mit den CASE) werden in 60ms ca.1900 Schleifendurchgänge mit jeweils ZWEI GDI(+)-Funktionen aufgerufen. Also SO schlecht ist da GDI nicht!!


    Zusammengefasst:

    Das was das Script so "langsam" macht, sind (wie so oft) die Berechnungen innerhalb der Schleifen.

    Es lohnt sich also definitiv, diese Berechnungen auszulagern, bspw. in eine DLL.

    Ich reite jetzt bestimmt nicht wieder auf Assembler rum ( Mars bekäme das sicher auch mit AVE/SSE unter Ausreizung aller vom Prozessor verfügbaren Möglichkeiten incl. Multithreating (das auch in AutoIt!) hin), aber jeder beliebige Compiler schafft die Berechnungen heutzutage mit mindestens dem Faktor 1000 schneller! UEZ würde da FreeBasic nutzen!

    Also mal angenommen, die o.g. Berechnungs-Schleifen würden in Summe je 1ms brauchen (also vernachlässigbar), dann bleiben je Haupt-Schleifendurchlauf die 60ms für die 3800 GDI-Funktions-Aufrufe. Ob DAS ein Compiler auch nur Faktor 5-10 schneller macht, wage ich zu bezweifeln! Aber Versuch macht kluch!

    Letztendlich führen die in einen Assembler/Compiler ausgelagerten Berechnungs-Funktionen zu einer Beschleunigung des Scripts um ca. Faktor 3-4, bei mir würden da doch ansprechende 15FPS rauskommen. Und zwar UNABHÄNGIG von der Anzahl der Polygone!

    Das Script komplett 1:1 in FreeBasic umgesetzt schätze ich mal erreichbare 25-30FPS mit GDI(+). Die Verwendung von D3D wäre allerdings, abhhängig von der Grafikkarte, unendlich viel schneller....

    Fazit:

    Die "brotlose Kunst" ist LEIDER nicht die Stärke von AutoIt, um aber mal fix bissl Grafikgedöns hinzuzaubern, immer gut :P .

    Daher :thumbup:

  • WMI Abfrage

    • Andy
    • 25. Januar 2023 um 12:12

    Wie water schon anmerkte, ist Scriptomatic das Tool der Wahl! Dann passiert

    Zitat von casi4712

    leider zeigt er mir nur den ersten gefundenen Eintrah sn mit

    das auch nicht....

    Ich hatte in Scriptomatic noch einen Filter(button) integriert, damit man nicht ellenlang durch die Liste scrollen muss.

    Scriptomatic.au3

    Übrigens kann man auch, nachdem man auf den Pfeil im rechten Dropdown geklickt hat und die Liste sieht, ein Leerzeichen eingeben und es wird ein "leeres" Abfragengerüst erstellt! Die (SQL)Abfrage muss dann nur noch ergänzt werden...

    Die erstellten Abfragescripte sind natürlich ohne Scriptomatic lauffähig, sie befinden sich als Datei im TEMP-Ordner und werden von Scriptomatic nach deren Ausführung gelöscht.

    Um weitere Ideen in bestehende Scripte einfließen zu lassen und diese umzuschreiben und auf eigene/andere Bedürfnisse anzupassen, dafür ist ja ein Forum bzw. die Community da!

    Auch BugFix hat sich mit dem Thema beschäftigt!

    Man muss also nicht (auch wenn es ab und zu Spass macht^^) das Rad neu erfinden!

  • Variable used without being declared - nach dem compilieren

    • Andy
    • 19. Januar 2023 um 09:17
    Zitat von SOLVE-SMART

    auch 'ne Möglichkeit 👍 . Kannte ich noch nicht und führt sicherlich zum gleichem Ziel. Ist für mich persönlich nicht relevant, da ich seit Jahren nur noch mit VSCode arbeite und nicht mit Scite, dennoch Danke für die Ergänzung 🤝 .

    Würde mich SEHR stark wundern, wenn ein x-beliebiger Editor (der seinen Namen verdient) das nicht seit Jahren könnte... 8)

    Es soll sogar Editoren geben, welche "intelligent" Backups anlegen (können) =O Wobei ich mich jetzt frage, wieso Scite das nicht kann... :/

    Ein Werkzeug ist eben nur so gut wie die Aufgabe die dazu passt :ironie:.Aber das gehört in den anderen aktuellen Thread :rofl:

  • Performance-Analyse der neuen Datenstruktur "Map"

    • Andy
    • 18. Januar 2023 um 16:26
    Zitat von AspirinJunkie

    Kurz: Wir interessieren uns für Lösungen des eigentlichen Problems - nicht für Workarounds.

    So ist das...

    Wenn durch eine Methodenänderung/Umstrukturierung/Umprogrammierung der Faktor 2 erreicht werden kann, dann wird mir als hauptberuflicher Optimierer schon warm ums Herz :saint:

    Die Frage ist, ob der Dev davon wissen will, und ob er Problem- oder Lösungsorientiert arbeitet!? Ich jedenfalls bin immer froh, wenn ich Rückmeldung erhalte wenn etwas NICHT funktioniert, bzw. jemand eine gute oder bessere (als meine) Idee hat. Nur so kann man sich und den Ablauf verbessern. Das übliche ist aber, wenn problemorientierte Leute dann ein riesen Fass aufmachen, um von einem Ablauf, der bei 95% Erfolgsquote läuft, noch 0,2% "MEHR" rauszuholen....wobei eigentlich jeder wissen sollte dass es immer schwieriger wird, einen bereits optimierten Prozess weiter zu verbessern. Wenn überproportional viel Ressourcen, Manpower und Equipment benötigt wird, dann lohnt der Aufwand einfach nicht.

    Ich bin da pragmatisch: funktioniert, ist schnell, einfach und gut umzusetzen--->MACHEN! Ansonsten ans Ende der Prioritätenliste :whistling:

    Zitat von AspirinJunkie

    Das Problem mit den Array-Indizes ist ein klares Beispiel für den Fall, dass die Software weit entfernt ist von einer möglichst optimalen Ausnutzung der vorhandenen Hardwareleistung.

    Das gilt nicht nur für die Array-Indizes! Wobei ich ganz klar sagen muss, dass AutoIt, obwohl seit Jahren nicht mehr "weiterentwickelt" (ich rede nicht von dem immer mal implementierten Spielkram, siehe Thema ^^) wurde, ziemlich gut und "relativ" bugfrei läuft. "Richtige" Bugs habe ich jedenfalls schon seit Jahren nicht mehr gemeldet....und den Rest spare ich mir, um meine Nerven zu schonen 8o

    Zitat von BugFix

    Ist aber nur eine Vermutung - in die inneren Abläufe können wir ja leider nicht reinschauen.

    Hehe....ob ich das überhaupt will?! Nicht vorzustellen was passieren würde, sollte jemand sich näher damit befassen und entsprechend "atemberaubende" Änderungen aufzeigen....mimimimimi.... :rofl:

  • Performance-Analyse der neuen Datenstruktur "Map"

    • Andy
    • 18. Januar 2023 um 07:50
    Zitat von Mars

    Die Devs haben dazu damals gesagt, dass das eben so ist weil es intern aus irgendwelchen Gründen so gemacht wird.

    Naja, dann ist das eben so^^....genau wie das kopieren von (Text-) Variableninhalten bei sämtlichen "internen" Funktionen. Leg mal einen mehrere hundert MB großen Text an und lass auf diesen dann die durchaus schnellen Text/Stringfunktionen los und beobachte die Speicherauslastung....dabei hatte ich festgestellt, dass die Ausführungsgeschwindigkeit der Funktionen teilweise höher ist als die Zeit, den Speicherbereich zu kopieren...auch so kann man ein Programm "verlangsamen" 8o

    Was logisch erscheint, sind doch die "blauen" aka internen Funktionen nichts weiter als gewrapperte C(++)-Funktionen aus den standardisierten Bibliotheken. Da erfindet niemand das Rad neu! Die Laufzeit "innerhalb" der Funktion ist also identisch mit der eines kompilierten Programms!

    Was die Zeit frisst, ist der "selbstgestrickte" Overhead. Und mit Sicherheit die Art und Weise der Programmierung. Ja, was mir schon vor beinahe 40 Jahren Ärger mit HP einbrachte, als ich denen als "dummer" Maschinenbaustudent einen Auftrag von mehreren hunderttausend DM versaute, weil ich einen Grafiktreiber eines CAD-Systems (damals ME30) umgeschrieben und so um mehrere Faktoren beschleunigt hatte. So bestand für die Hochschule auch kein Grund, die "neuen" (und schnelleren) Systeme zu kaufen. Damals war ich noch stolz darauf, bis ich bei der folgenden CBIT hochkant vom HP-Messestand flog, mit Geleitschutz wie ein Schwerverbrecher....

    Was musste ich auch die Schnauze aufreißen und sagen, dass ein langsames und "schlechtes" Programm auch nicht schneller und besser wird, wenn man es durch einen "neuen" C-Compiler jagt....Es führt den "schlechten" Code nur schneller aus^^

    Zitat von Mars

    Für Arrays gilt: Lesender Zugriff -> Index wird 1x evaluiert, Schreibender Zugriff -> Index wird 2x evaluiert (glaube ich).

    Wenn dann noch, wie bei den Strings, die Variablen aka der komplette Array-Speicherbereich vor jeder Operation kopiert werden, dann braucht man sich nicht wundern...ByRef ftw!

  • Variable used without being declared - nach dem compilieren

    • Andy
    • 18. Januar 2023 um 07:21
    Zitat von SOLVE-SMART

    Bzgl. "was der Unterschied zu gestern ist" kann ich nur zu GIT bei deinem Projekt raten.

    Scite speichert *.bak-files in beliebiger Iterationstiefe ab, einstellbar in Scite-Config (CTRL-1) auf dem ersten Reiter (Backup Strategy)!

  • Variable used without being declared - nach dem compilieren

    • Andy
    • 17. Januar 2023 um 12:05

    Racer, das ist doch ein wirklich schönes, kleines, strukturiertes Programm, und du willst mir allen Ernstes erzählen, dass du nicht innerhalb weniger Minuten mit DEBUG-MESSAGEBOXEN (Scite CTRL-SHIFT-D) die Zeile mit dem declare-Fehler findest?

    Was ich anhand deiner Variablennamen eher vermute, ist ein Fehler beim Aufruf einer Unterfunktion, ggf. auch in einer der UDF, bei der dieser Variablenname gelöscht bzw. mit anderem Typ (array?!) besetzt wird.

    Leider gibt es in Scite im Tools-Menü kein "Add Tracelines" welche Messageboxen statt Konsolenausgaben verwenden.

    Dann musst du diese Debug-Messageboxen per CTRL_SHIFT_D von Hand setzen

    Zitat von Racer

    Da ja die GUI angezeigt wird und erst danach die Fehlermeldung kommt, habe ich an an verschiedenen Stellen im Script ein "exit" eingebaut um zu sehen wie weit es läuft. Auch das hat mich nicht wirklich weiter gebracht.

    Wieso? Du kennst doch den Ablauf in deinem Programm am besten?! Setze Debug-Zeilen jeweils vor und hinter die Funktionsaufrufe, wenn du die Funktion die den Fehler wirft dann lokalisiert hast, machst du das Prozedere innerhalb der Funktion weiter....so lange, bis vor der "fehlerhaften" Zeile im Code eine Messagebox erscheint, und wenn du diese dann wegklickst, die Fehlermeldung.

    Btw könntest du auch die Tracelines verwenden und im Script dann global alle "Consolewrite" mit einer eigenen (Log-)Funktion ersetzen, die statt die Zeile in die Konsole in eine Datei schreibt. Dann hast du in der letzten Zeile der log-Datei deinen Fehler :)

  • Performance-Analyse der neuen Datenstruktur "Map"

    • Andy
    • 17. Januar 2023 um 08:49

    Mars , ich zitiere mich mal selbst aus diesem Thread:

    Zitat von Andy

    Ich konnte die Ergebnisse von dir verifizieren, plus minus 10-20% in den Zeiten sehe ich bei diesen Laufzeiten der Scripte bei AutoIt einfach mal als "gleich" an^^

    AutoIt ist ein Interpreter, die Ausführungsgeschwindigkeit von programminternen Vorgehensweisen ist also primär vom Skill des Programmierers/Developers und der von ihm verwendeten Werkzeuge/Funktionen/Frameworks des Interpreters abhängig, s. dazu auch Post #27, letzter Absatz!

    Natürlich hast du recht, wie AspirinJunkie übrigens auch.

    Die "Intention", einen Datenwert in einer (im Speicher stehenden) Liste über einen Index abzurufen, ist bei sämtlichen dieser Methoden gleich. Aus Prozessorsicht ist das, auch bei "verketteten" Listen, eine Sache von einer Handvoll Prozessortakte, also quasi nicht messbar!

    Ein interpretierter AutoItcode ist, und das weist du ziemlich gut :rock: , ca. 1000x langsamer bei Rechenfunktionen in (verschachtelten) Schleifen als entsprechender compilierter Code. Da spielen derart viele Faktoren in die Ausführungszeit rein...s. dein 2. Chart Mapzeit/Arrayzeit...die "Peaks" bei Vektorlänge 16 und 20 sind ggf. irgendwelche Festplattenzugriffe, schicken des Prozessors in den Stromsparmodus (ja, WÄHREND des Benchmarks^^) uswusf.

    Der Overhead beim Benchen muss dementsprechend so niedrig wie möglich gehalten werden, macht aber, und das ist ja einfach nachzuweisen, im vorliegenden Fall KEINEN Unterschied....

    Wenn es also wirklich auf Geschwindigkeit ankommt (und das meine ich nur im Bezug zu den auch hier im Forum von mir befürworteten Wettbewerben), dann MUSST du die schnellste Methode/Programmieridee verwenden: :P

    Zitat von AspirinJunkie

    Das die System.Collections.Hashtable nun aus dem Test herausgefallen ist, hat aber auch einen positiven Aspekt: Nun ist meine in purem AutoIt geschriebene Hashtable nun offiziell die schnellste Datenstruktur beim Lesen aus assoziativen Strukturen bei 1 Million Elementen! :D

    WZBW!!! :party:

  • Text Konvertierung

    • Andy
    • 6. Januar 2023 um 10:28

    Naja, nur gut, dass nicht nur ich dieses "Problem" habe!

    Zitat von AspirinJunkie

    Die Quelle soll nirgends verändert werden.
    Sie soll nur von Anfang an exakt so behandelt werden wie sie tatsächlich beschaffen ist.

    Und genau hier liegt der Hase im Pfeffer! Imho ist es nicht die Sache der Anwender, sich für die DARSTELLUNG der Daten die passende Kodierung heraussuchen zu müssen! So etwas gehört in eine Dokumentation!

    Mein täglich Brot als "Kunde" war u.a. die Abfrage einer Terabyte-großen ERP-Software-Datenbank mit mehreren tausend Tabellen, das ERP-Programm wurde zu allem Überfluss von einem international agierenden Team erstellt.

    So lange man mit der GUI dieses Programms zu tun hatte, war "meistens" alles in Ordnung, d.h. die deutschen Sonderzeichen wurden auch entsprechend dargestellt.

    Aber schon beim Ausdruck der Daten kam es "manchmal" bei deutschen Sonderzeichen zu Problemen. Hinweise auf "Probleme" in der Kodierung der Tabellen bzw. deren Abfrageergebnisse wurden seitens Programmhersteller "abgewatscht", viel zu kompliziert, uber Jahre gewachsenes Programm mit internationalem Hintergrund, blabla...

    Für die Bereitstellung interner Daten(zusammenhänge) hatte ich mir dann mehrere Tools in VBA geschrieben. Dabei ist mir aufgefallen, dass je nach Gusto des DB-Programmierers und dessen globalen Standort, "willkürlich" eine Kodierung beim Anlegen einer Tabelle gewählt wurde! Was in der GUI natürlich völlig problemlos ist, da der GUI-Programmierer mit seinem Datenbankspezi im gleichen Raum sitzt und ALLE Spezifikationen einsehen und somit in seiner Darstellung anpassen kann. Die "Erweiterung" auf Webinterfaces mit HTML und entsprechender Abfragen macht das Chaos perfekt! Übergabe von Daten an Programme anderer Hersteller, durch AutoIt automatisiert? Viel Spass!

    Als ANWENDER hast du bis auf rudimentäre Dokumentation NICHTS (außer Sodbrennen)!

    Ich also quer über den Wust an Daten fleißig Tabellen verknüpft und Abfragen gestaltet, die Daten dann entweder per VBA in Officeprodukten dargestellt, auf diverse Druckmedien (Papier, Etiketten, Laserbeschrifter uswusf.) ausgegeben und mich jedes Mal über die Mehrarbeit gefreut, wenn deutsche Sonderzeichen nicht "richtig" behandelt wurden.

    Zu allem Überfluss hatte ich dann den gesamten Ablauf auf Barcodes umgestellt, was wiederum die Probleme vervielfacht hat. Ja, auch Scanner, die in meinem Fall mit mehreren Softwareprodukten unterschiedlichster Hersteller zusammenarbeiten müssen/sollen, habe unterschiedlichste Einstellungen in der Kodierung!

    Bring mal mehrere Software- und Hardwarehersteller unter einen Hut, die ALLE eine WILLKÜRLICHE Kodierung verwenden!!!

    Wenn man sich mit dem Thema intensiv beschäftigen muss, dann tun sich einem ABGRÜNDE auf!

    Da werden von einem Maschinenhersteller Barcode-Handscanner für eine Maschine für 1500 Euro per Stück "konfektioniert" angeboten, obwohl der 50€-Scanner das ebenso kann! Warum?! Nicht etwa, weil der Scanner so "toll" ist, sondern weil er im Auslieferungszustand des Scanner(!)herstellers auf eine bestimmte Kodierung eingestellt ist....Scanner defekt, neuen bestellt, auspacken, anschließen, läuft.

    50€-Scanner bestellt, ausgepackt, angeschlossen, KODIERUNG LT. HANDBUCH GEÄNDERT/AUF MASCHINE ANGEPASST, angeschlossen, läuft.

    Etikettendrucker das gleiche Spiel!

    Ich behaupte mal, 99,9 % aller "Anwender" sind nicht in der Lage, den "Fehler" einer abweichenden Kodierung zu erkennen, die "sehen" nur "falsche" Zeichen! Wenn sie überhaupt irgendetwas sehen, meistens "funktioniert" nur etwas einfach nicht! Respektive Maschinen, die nicht funktionieren (können) weil "falsche" Zeichen übermittelt werden. Und kaum eine Software/Hardware kann "einfach" abgepasst/umgestellt werden!

    Ich habe mich diesem Procedere angepasst! Ich habe mir in diversen Programmiersprachen (Test-)Filter und Module geschrieben, die dieses "Manko" beheben. Ich schieße mit einer speziell dafür angelegten Testabfrage per SQL auf eine Datenbank (aka API auf ein Webinterface), deren Kodierung ist mir VÖLLIG wurscht, das Ergebnis wird in eine Tabelle geschrieben und die "richtige" Kodierung (bzw. mein Filter) für die Weiterarbeit ausgewählt. Das funktioniert bei allen Abfragen! Auch bei Hardware (Barcodescannern), die dann entsprechend umprogrammiert werden....

    Btw, Regexe zum "erkennen" invalider Kodierungen sind mein Freund....

    Und ja, ich bin KEIN Programmierer! Ich habe 90% meiner Arbeit mit ganz anderen Dingen zu tun....da fragt sich irgendwann der Normalsterbliche, was gestandene "Programmierer" zu diesem Thema sagen?! Meine Erfahrung nach etlichen Jahrzehnten.....die sagen NICHTS dazu, sind meistens völlig Hilflos und verweisen auf den Support des "anderen" Software/Hardwareherstellers! Industrie 4.0 anyone?!

Spenden

Jeder Euro hilft uns, Euch zu helfen.

Download

AutoIt Tutorial
AutoIt Buch
Onlinehilfe
AutoIt Entwickler
  1. Datenschutzerklärung
  2. Impressum
  3. Shoutbox-Archiv
Community-Software: WoltLab Suite™