_Singleton Fensterhandle

  • Hallo,

    wenn eine Instanz bereits von dem Skript läuft – auch wenn sie minimiert ist – möchte ich sie aktivieren.

    Über den Fenstertitel kann ich die vorherige Instanz nicht identifizieren, der dieser mehrfach während der Laufzeit geändert wird.

    C
    #include <Misc.au3>
    #include <MsgBoxConstants.au3>
    
    If _Singleton("Skript", 1) = 0 Then
        MsgBox($MB_SYSTEMMODAL, "Warnung", "Eine Instanz des Skripts wird bereits ausgeführt!")
        $handle = ... bereits laufenende Instanz ... ???
        WinActivate($handle)
        Exit
    EndIf
    MsgBox($MB_SYSTEMMODAL, "Alles i.O.", "Die erste Instanz des Skripts läuft.")

    Wie erhalte ich das Handle von jenem Prozess, den _Singleton als bereits zuvor gestarteten Prozess erkannt hat?

  • Wenn mit der Funktion _Singleton der zuerst gestartete Prozess erkannt wird

    Es wird nicht direkt ein Prozess erkannt, sondern das von diesem erzeugte Mutex Objekt... und ich wüsste jetzt nicht, wie man damit an das Handle des Fensters kommt.

    Doch mit einem versteckten Label ist das kein Problem - so würde ich es machen:

  • Mutex Objekt.

    Wie kann man Mutex Objekt am einfachsten erklären? Bei Wiki und Co nachgelesen, aber so richtig einleuchtend ist mir nicht, was ein Mutex Objekt ist.

    Doch mit einem versteckten Label ist das kein Problem - so würde ich es machen:

    Danke für den Lösungsansatz - eine gute Idee.


    Was haltet Ihr von folgendem Ansatz und wie kann man den verbessern?

    Code
    #include <Crypt.au3> 
    $titel = _Crypt_HashFile(@ScriptFullPath,$CALG_MD5)

    Erhält man so den Hash für die Datei, den man in den Fenstertitel ans Ende als unveränderlichen und eindeutigen Wert setzen könnte?

    Dann könnte wieder winactivate verwendet werden.

    Problem bei dieser Variante wird sein, dass eine kompilierte exe-Datei einen anderen Hash hat als die ausgeführte .au3-Datei hat – richtig?

    Gibt es eine bessere Möglichkeit, einen eindeutigen Schlüssel für eine au3 und die zugehörige kompillierte exeDatei automatisiert zu erstellen, der im Fenstertitel am Ende eingebunden wird? Der Schlüssel muss für die au3 und die zugehörige kompillierte exeDatei identisch sein.

    Ein anderes AutoIt-Skript (egal ob kompiliert oder nicht) soll in der Ausführung nicht den gleichen Schlüssel erhalten können.

  • Wie kann man Mutex Objekt am einfachsten erklären?

    Ich finde bei Wikipedia ist es gut erklärt...

    Der Begriff wechselseitiger Ausschluss bzw. Mutex (Abk. für englisch mutual exclusion) bezeichnet eine Gruppe von Verfahren, mit denen das Problem des kritischen Abschnitts gelöst wird. Mutex-Verfahren verhindern, dass nebenläufige Prozesse bzw. Threads gleichzeitig oder zeitlich verschränkt gemeinsam genutzte Datenstrukturen unkoordiniert verändern, wodurch die Datenstrukturen in einen inkonsistenten Zustand geraten können, auch wenn die Aktionen jedes einzelnen Prozesses oder Threads für sich betrachtet konsistenzerhaltend sind. ...

    In der Funktion _Singleton wird so ein Mutex erzeugt... der enthält u.a. den OccurrenceName und eine DACL (discretionary access control list).

    https://docs.microsoft.com/en-us/windows/…ydescriptordacl

    https://docs.microsoft.com/en-us/windows/…pi-createmutexw

    Ist uns aber eigentlich egal, was in dem Mutex ist... wichtig ist nur, dass wir wissen, wenn der Mutex bereits vorhanden ist und versucht wird, einen zweiten zu erstellen, die Funktion _Singleton dann 0 (False) und den Fehler $ERROR_ALREADY_EXISTS (183) zurückgibt.

    Was haltet Ihr von folgendem Ansatz und wie kann man den verbessern?

    Keine gute Idee... denn dann darf das Script nicht mehr bearbeitet werden, da sich sonst ja auch der Hash ändert und somit nicht mehr gefunden wird.

    Dann besser einmalig eine GUID (_WinAPI_CreateGUID) erzeugen... davon kann dann ein Hash (weil kürzer) erzeugt werden... der dann als fixer Bestandteil des Fenstertitels verwendet wird. Oder schaue dir mal die Funktion _WinAPI_HashString an.

    Doch wozu der ganze Aufwand, wenn es auch ohne geht?

    Ich kenne viele Programme, bei denen sich der Titel ständig ändert... alle haben eines gemeinsam... ein Teil des Titels bleibt immer gleich - so handhabe ich das auch in meinen Scripten. Um das Handle nicht nur anhand eines Teils des Titels zu bestimmen, prüfe ich auch den ClassName (_WinAPI_GetClassName) des Fensters.

    Total Commander Ultima Prime 7.3 :: CPU: 022% (3,2 GHz) :: RAM: 078% (6,0 GB) :: C: 50% :: 09.09.2020 - 02:46:22 :: 03:07:43 ::

    F:\Eigene Dateien\TxT\ToDo.txt - Notepad++

    C:\Program Files (x86)\AutoIt3\Include\Misc.au3 - SciTE [20 von 20]

    Einmal editiert, zuletzt von Bitnugger (9. September 2020 um 03:35)

  • Keine gute Idee... denn dann darf das Script nicht mehr bearbeitet werden, da sich sonst ja auch der Hash ändert und somit nicht mehr gefunden wird.

    Das Skript darf bearbeitet werden, da der/die/das Hash bei jedem Aufruf von dem Skript erneut berechnet wird und erst dann Bestandteil der Fenster-Titelzeile wird.

    Wird das unveränderte Skript erneut aufgerufen, wäre der neu berechnete Hash identisch mit der vorher gestarteten Instanz - richtig?

    Code
    #include <Crypt.au3> 
    $titel = _Crypt_HashFile(@ScriptFullPath,$CALG_MD5)
    winsettitle ...$titel

    Ich kenne viele Programme, bei denen sich der Titel ständig ändert... alle haben eines gemeinsam... ein Teil des Titels bleibt immer gleich

    Dafür wollte ich einen Hashwert nehmen, da dieser eindeutig wäre.

    Um 99 Kiwis auseinanderzuhalten, ist ein automatisch berechnetes "Kiwis Hashwert" im Titel für mich einfacher als Kiwi 3, 4 ... ups ... wieviele Kiwis hatte ich bereits programmiert?

    Die von Dir zitierten Programme wie TC und Co sind per se unterschiedlich (Funktion, Name ...).

    Bei mir gibt es x Fenster "Kiwi" (kleine und annähernd fast identische Tools), die einen erkennbaren, automatischen Zusatz im Titel brauchen.

    Daher die Idee mit dem Hash des Scripts im hinteren Titelteil.

    Danke für die interessanten Anregungen.

    Staffelstab: Nur derjenige der ihn gerade besitzt darf rennen, alle anderen müssen warten bis der Läufer ihn wieder freigibt.

    verstanden :)

  • Das Skript darf bearbeitet werden, da der/die/das Hash bei jedem Aufruf von dem Skript erneut berechnet wird und erst dann Bestandteil der Fenster-Titelzeile wird.


    Wird das unveränderte Skript erneut aufgerufen, wäre der neu berechnete Hash identisch mit der vorher gestarteten Instanz - richtig?

    Klingt interessant. Poste mal Code dazu. :)

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

  • Klingt interessant. Poste mal Code dazu.

    Der steht in Post 5/8 - hier nochmal.

    Laut bisherigem Feedback soll das keine so gute Idee von mir sein. Ich werde das mal über längere Zeit testen, ob das für mich ein praktikabler Weg wäre.

    Code
    #include <Crypt.au3> 
    $titel = _Crypt_HashFile(@ScriptFullPath,$CALG_MD5)
    winsettitle ...$titel
  • Der steht in Post 5/8 - hier nochmal.

    Lässt du dir jetzt alles aus der Nase ziehen? 8o

    Du sollst ein lauffähiges Beispiel posten. Oder denkst du, jemand der dir helfen soll, will sich die Arbeit machen, auch noch das Drumherum zu erstellen?

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

  • Wird das unveränderte Skript erneut aufgerufen, wäre der neu berechnete Hash identisch mit der vorher gestarteten Instanz - richtig?

    Richtig, gleicher Dateiinhalt = gleicher Hash. Ändert sich der Dateiinhalt (und somit auch der Hash), kann eine zuvor gestartete Version aber nicht mehr erkannt werden. Ich denke, den Hash des Dateiinhalts zu verwenden, hat nur dann einen Mehrwert, wenn unterschiedliche Versionen/Varianten des Scripts bei deiner Entscheidung berücksichtigt werden sollen. Falls nicht, ist es wohl sinnvoller, einen Hash von @ScriptFullPath oder @ScriptName mit _WinAPI_ComputeCrc32, _WinAPI_HashString oder _Crypt_HashData zu erzeugen.

    Im Anhang findest du zwei kleine Demos... mit verschiedenen Hash-Funktionen... inkl. einer erweiterten WinGetHandle-Funktion (REGEXPTITLE, CLASS, INSTANCE).

  • Falls es den Rahmen nicht sprengt - sonst später als eigenständiges Thema:

    Wie funktioniert die Berechnung der ASIN bei Amazon?

    Beispiel:

    B009GK1NDI

    Gibt man diese Nummer bei Amazon ein, hat man das Produkt aus Millionen anderer Produkte eindeutig identifiziert.

    ASIN bei Amazon sind eindeutige Gruppen von 10 Buchstaben und/oder Ziffern, anhand derer Artikel identifiziert werden.

    Nur 10 Zeichen lang - sowas würde ich gerne für meine Scripte verwenden.

    Dagegen ist ein md5 Hash enorm lang - Beispiel - 0x5B961A0BD72FA9A21E66DEAE4806B7E0

    B009GK1NDI

    statt

    0x5B961A0BD72FA9A21E66DEAE4806B7E0

    wäre top.

    Wie kann ich sowas eindeutiges und kurzes mit AutoIt aus der Datei c:\test\test.au3 generieren?

    (Also eine "eindeutige Gruppen von 10 Buchstaben und/oder Ziffern", die stellvertretend für die Datei c:\test\test.au3 steht?)

    Ich kenne mich mit Kombinatorik / Permutationen nicht aus und kann aus dem ff nicht sagen, wie viele Varianten es bei 10 Buchstaben und/oder Ziffern gibt.

    Weiß das jemand von Euch?


    Ändert sich der Dateiinhalt (und somit auch der Hash), kann eine zuvor gestartete Version aber nicht mehr erkannt werden

    Das verstehe ich – allerdings bin ich gar nicht auf den Gedanken gekommen, dass jemand ein Skript laufen lässt, es erst dann ändert und dann eine zweite Instanz davon startet und eventuell erwartet, dass der Hash identisch bleibt.

    Wenn ich ein Skript geändert habe, dann beende ich zuvor die laufende Instanz des gleichen Scripts, bevor ich es das erste Mal starte.

    Ab dem zweiten Start würde der Hash in der Titelzeile mit der ersten Instanz übereinstimmen, wie das Beispiel unten zeigt.

    So erkenne ich, dass es das gleiche Script ist und das ist mein Ziel. Ein Hash ist mir im Vergleich zur obg. ASIN nur zu lang.

    Danke für die Anregung und für Deine hilfreichen Zeilen.


    aus der Nase ziehen

    Professor Bernd - hier etwas lauffähiges.

    Code
    #include <Crypt.au3> 
    $titel = _Crypt_HashFile(@ScriptFullPath,$CALG_MD5)
    MsgBox ( 0 , " aus der Nase ziehen - " & $titel , "So sieht die Titelzeile eines Fensters aus - hier am Beispiel eines lauffähigen Messagebox-Fensters." )

    In meinem Post vor Deiner Aufforderung schrieb ich:

    "Wird das unveränderte Skript erneut aufgerufen, wäre der neu berechnete Hash identisch mit der vorher gestarteten Instanz ..."

    Startest Du das Script aus diesem Post 2x als au3 Datei (oder 2x als exe), erhälst Du 2x Messageboxen mit dem gleichen Hash im Titel des Fensters.

  • Nur 10 Zeichen lang - sowas würde ich gerne für meine Scripte verwenden.

    Dagegen ist ein md5 Hash enorm lang - Beispiel - 0x5B961A0BD72FA9A21E66DEAE4806B7E0

    Wie von Bitnugger beschrieben, sind die Hash-Funktionen bereits etabliert. Es ist ja nicht so, dass Du Hashwerte laufend von Hand eintragen musst (die Länge spielt also keine Rolle ^^).

    EDIT :

    [...] wie viele Varianten es bei 10 Buchstaben und/oder Ziffern gibt.Weiß das jemand von Euch?

    Anzahl der Zeichen HOCH Länge

    Gruß Musashi

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

    Einmal editiert, zuletzt von Musashi (11. September 2020 um 08:42)

  • Wie funktioniert die Berechnung der ASIN bei Amazon?

    Gar nicht. Die ASIN ist kein Hash die aus irgendwelchen Produktinformationen berechnet wird sondern lediglich ein eindeutiger Bezeichner innerhalb der Amazon-Datenbank.
    Die wird automatisch vom System vergeben (z.B. durch Hochzählen) und bei der Vergabe darauf geachtet, dass die ID nicht bereits in der Datenbank vorkommt.

    Wie kann ich sowas eindeutiges und kurzes mit AutoIt aus der Datei c:\test\test.au3 generieren?

    (Also eine "eindeutige Gruppen von 10 Buchstaben und/oder Ziffern", die stellvertretend für die Datei c:\test\test.au3 steht?)

    Einen Hash-Algorithmus nehmen, der weniger Stellen hat. CRC-32 z.B.

    Auch den md5-Hash kürzen geht ebenso.

    In beiden Fällen hat man jedoch einen kleineren Pool möglicher Varianten und damit eine höhere Wahrscheinlichkeit von Kollissionen.

    Ich kenne mich mit Kombinatorik / Permutationen nicht aus und kann aus dem ff nicht sagen, wie viele Varianten es bei 10 Buchstaben und/oder Ziffern gibt.

    Weiß das jemand von Euch?

    Eine md5 Checksumme hat 128 Bit - also 2^128 verschiedene Möglichkeiten = 3,4028237 * 10^38
    In hexadezimaler Schreibweise braucht man weniger Stellen - da sind es 32 Stellen (16^32 = 3,4028237 * 10^38).
    Wenn man nun also nur die ersten 10 Stellen der hexadezimalen md5-Checksumme nimmt, dann hätte man noch 16^10 = 1,0995116 * 10^12 Möglichkeiten übrig.

    Und wenn du es mit einem ganz eigenen Satz eines Alphabetes kodierst - z.B. alle Groß/und Kleinbuchstaben sowie Zahlen dann hätte man bereits mit 7 Stellen schon 62^7 = 3,5216146 * 10¹² verschiedene Möglichkeiten. Als Base64 hingeschrieben sogar noch nen Tick mehr: 64^7 = 4,3980465 * 10¹².

    Wieviele Kombinationen nun hingegen CRC-32 bietet und wieviel Stellen man hierfür bei hexadezimaler Darstellung braucht, kannst du dir nun selbst anhand der Info ausrechnen, dass CRC-32 32-Bit zur Verfügung hat.

    Einmal editiert, zuletzt von AspirinJunkie (11. September 2020 um 08:47)

  • Nur 10 Zeichen lang - sowas würde ich gerne für meine Scripte verwenden.

    Das kannst du mit _WinAPI_ComputeCrc32 machen...

  • Professor Bernd - hier etwas lauffähiges.

    Code
    #include <Crypt.au3> 
    $titel = _Crypt_HashFile(@ScriptFullPath,$CALG_MD5)
    MsgBox ( 0 , " aus der Nase ziehen - " & $titel , "So sieht die Titelzeile eines Fensters aus - hier am Beispiel eines lauffähigen Messagebox-Fensters." )

    Also doch aus der Nase ziehen! Ich sehe keinen Code zu deinem Thema _Singleton. Ich bin raus. :(

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.