Problem mit WIndows Context Menü und Shared-Variables - Programm verhält sich beim ersten Aufruf anders

  • Hallo Leute,

    ich hab hier ein Problem das ich nicht verstehe. Hab schon so mega viel getestet, aber ich versteh nicht warum es nicht klappt .. :D
    Erstmal etwas hinführendes:

    Wenn man in Windows ein Programm im Contextmenü von Dateien registriert und mehrere Dateien selektiert und dann den Befehl ausführt, wird das registrierte Programm mehrfach gestartet, anstatt einmal. Hierbei wird immer die selektierte Datei als Parameter übergeben. Also muss man hier ein Workaround machen. Es geht leider wirklich nicht anders ..
    Man könnte jetzt den Parameter den Windows übergibt in eine Datei schreiben und das Hauptprogramm diese ständig angucken lassen, aber das würde zu extrem vielen Festplattenzugriffen führen, was suboptimal ist :D
    Also erstelle ich eine Variable im RAM auf welche zwei Autoit-Exen zugreifen können. An sich keine schwere Sache dank der vielen UDFs die es für Autoit schon gibt.
    Doch leider verhält sich das Programm, wenn es durch Windows aufgerufen wird beim ersten Start anders, als bei den darauf folgenden.

    Ich weiß nicht ob ihr mir bis hierhin folgen könnt ..

    Ich habe meine Code auf die nötigen Stellen vereinfacht, damit das Problem nachvollzogen werden kann.
    Alle nötigen includes und eine compilierte Exe findet sich im Anhang.
    Bevor die Main.exe bzw. au3 ausgeführt werden kann muss einmal das Install-Script ausgeführt werden.

    Hier mal der Code vom Install:

    AutoIt: install.au3
    #RequireAdmin
    #AutoIt3Wrapper_UseX64=y
    
    
    Global $dest = "C:\Test"
    RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CommandStore\shell\test", "MUIVerb", "REG_SZ", "Test1")
    RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CommandStore\shell\test\command", "", "REG_SZ", $dest&"\test.exe %1 test1|test2")
    RegWrite("HKEY_CLASSES_ROOT\*\shell\Test", "MUIVerb", "REG_SZ", "test")
    RegWrite("HKEY_CLASSES_ROOT\*\shell\Test", "SubCommands", "REG_SZ", "test")


    Und hier der Code der Main.au3:


    Das ganze funktioniert so, dass die Main.exe eine zweite erstellt, in welche die PID des Hauptprozesses und die Speicheradresse im RAM geschrieben wird. Das muss leider so sein, da sich diese beiden Variablen bei jedem Start der Main.exe ändern. Die zweite exe wird von Windows aufgerufen, wenn man den Rechtsklick macht und übergibt den dabei als Parameter übergebenen Pfad inklusive der Parameter an das Main Script.
    Die Includes habe ich so angepasst, dass sie stand-alone sind und auch auf PCs ohne Autoit compiliert werden können.
    Das funktioniert alles ohne Probleme.

    Das Problem ist folgendes:

    Wenn ich zwei Dateien markiere, dann sollten der Pfad und die exe getrennt durch ein Pipe | in die shared Variable geschrieben werden.
    Dies geschieht allerdings nur beim zweiten Aufruf des Programms. Beim ersten wird nur eine hineingeschrieben. Warum weiß der Geier .. ?(:cursing:

    Getestet wird, indem zwei Dateien markiert werden und dann Rechtsklick -> test -> Test1

    Ich hoffe ihr könnt euch die Zeit nehmen um da mal einen Blick drauf zu werfen. Ich bin mit meinem Latein leider echt am Ende .. :/

    Vielen vielen Dank schonmal im Vorraus für eure Zeit! :)

    P.S.: Das Script (main.au3) funktionieren nur im compilierten Zustand und nur wenn es als x86 compiliert wurde

  • Ich weiß, daß die Lösung dieses Problems im Entwicklerforum zu finden ist.


    Das war die gute Nachricht, die schlechte ich habe es mir nicht verlinkt und habe im Moment auch wenig Zeit.


    ...


    Wir haben zwar erst Montag, sollten deine Rechechern aber nicht erfolgreich sein erinnere mich am Samstag daran.

    Habe mich etwas getäuscht, ich habe es nur dort schonmal verlinkt:
    Prog übergibt Parameter an seine 1 Instanz (mehrere Dateien via Kontext-Menü)


    ist zwar schon älter, funktioniert aber auch unter der aktuellen Stable.

  • Das ist eine coole Lösung und funktioniert auch bestens. Nach einigem weiteren Testen muss ich leider zu dem Schluss kommen, dass die Lösung mit den Shared-Variablen leider zu unzuverlässig ist. Das wäre die einfachste Lösung gewesen.
    Ich hab jetzt auch ein wenig an dieser Lösung herumprobiert, aber ich weiß leider nicht wie ich das für mich praktikabel machen kann ..
    Ich weiß in diesem Fall nicht, wann alle Parameter übergeben worden sind und auch nicht, wie ich diese dann für mich nutzbar machen kann. Ich brauche die als String, getrennt mit Pipe, damit ich mit meinen Funktionen anfangen kann.
    Das GUI kann ja bleiben, ich muss das ja nicht unbedingt zeigen, damit es funktioniert.

    Weiß jemand wie ich da, nach beenden der Aufrufe alles auslesen kann? ?(

    Edit: Ok, ich weiß jetzt ca. wie ich es machen werde. Es läuft ja eh eine anderes Programm, welches dann checken kann ob diese Exe ausgeführt wurde. Da diese exe mehrfach startet und dann wartet, muss das Hauptprogramm nur so lange warten bis nur noch eine Instanz vorhanden ist. Dann muss es diese einfach auslesen.
    Ich hänge momentan nur noch am auslesen. Die hwnd der Control in die geschrieben wird bekomme ich raus, schaffe es aber noch nicht sie auszulesen ..

    Ich habe das Script von eukalyptus etwas angepasst, weil ich gehofft hatte, dass ich dieses so besser auslesen kann, aber das klappt trotzdem noch nicht :/

    Hier die Variante:

    Und hier das Script zum auslesen:



    Irgendwelche Ideen? :)

    Edit2: Ok, ich habs jetzt gelöst. Mit ListBoxen funktioniert da auslesen aus dem anderen Programm. Auch wenn man das GUI des anderen nicht zeigt :)

    2 Mal editiert, zuletzt von Leo.1906 (5. Juli 2016 um 11:02)

  • Nach noch mehr tests muss ich leider sagen, dass eukalyptus Variante genau so Fehlerbelastet ist wie die mit den Shared-Variablen ..

    Edit: ich war wohl etwas voreilig, tut mir leid :D
    Die Variante mit den Shared-Variablen ist die absolut beste. Das Problem hier wird wohl ein Race Condition Bug gewesen sein. Deswegen hat es mal funktioniert und mal nicht. Es darf natürlich nicht passieren das zwei Instanzen zeitgleich auf die Variable zugreifen und noch schlimmer, sie verändern. Ich habe die Exe, die erstellt wird, jetzt so angepasst das sie wartet bis die vorherigen geschlossen sind und dann erst schreibt. Ich dachte das hätte ich schon gemacht, aber das war grob fehlerhaft programmiert :D
    Außerdem habe ich ein paar Sleeps entfernt, was performance-technisch keinen Unterschied macht, aber noch zusätzlich dazu beiträgt, dass das ganze jetzt 100% läuft. Ich habe beim Testen keinen einzigen Fehlerhaften Aufruf mehr feststellen können :)

    Einmal editiert, zuletzt von Leo.1906 (5. Juli 2016 um 20:20)