Frage zu seltsamen Verhalten von _WinAPI_CopyFileEx

  • Hallo Gemeinde,

    eine neue Frage die mich schon länger beschäftigt:

    Ich benutze zum Kopieren die o.g. Funktion. Das Problem damit ist, dass wenn das angezeigte Progressbarfenster (durch ProgressOn erzeugt) verschoben wird,
    wird die Aktualisierung der Progressbar unterbrochen und es gibt im Titel des Fenster die Meldung "Not Responding"

    Das ist mein Test-Code:

    Das seltsame daran: wenn ich den Code aus der Hilfe für _WinAPI_CopyFileEx ausführe, ist das Progressbar-Fenster blockiert, kann nicht verschoben werden und
    die Progressbar wird bis zum Ende aktualisiert. In meinem Code, der in Bezug auf alle Bestandteile der Aufrufe und der Func Progressproc identisch sein sollte, da CopyPaste,
    hält die Blockade nur bis > 5 % an, dann kommt es beim Verschieben des Fensters zu o.g. Fehlverhalten.

    Hat jemand bitte eine Erklärung dafür:?:

    p.s.: dass das Kopieren auch anders, z.b. mit UDf gemacht werden kann, ist mir bewusst!
    Ich möchte bitte nur die Erklärung für das Verhalten, wenn möglich und keine
    Vorschläge/Diskussionen wie das Kopieren anderweitig bewerkstelligt werden kann. ;)

    2 Mal editiert, zuletzt von hipfzwirgel (16. Mai 2024 um 14:28)

  • p.s.: dass das Kopieren auch anders, z.b. mit UDf gemacht werden kann, ist mir bewusst!
    Ich möchte bitte nur die Erklärung für das Verhalten, wenn möglich und keine
    Vorschläge/Diskussionen wie das Kopieren anderweitig bewerkstelligt werden kann. ;)

    Sehr guter Hinweis, ich wollte gerade ausholen 🤣 .

    Hat jemand bitte eine Erklärung dafür :?:

    Nein, nicht ohne zu recherchieren. Mal schauen was von den anderen dazu kommt 🤞 .

    Viele Grüße
    Sven

  • Ich vermute stark, dass es an dem Sleep(10) in der _ProgressProc liegt.

    Alle Hooks/Procs/... sollten so schnell wie möglich beendet werden. 10ms mag für dich kurz sein, ist aber für den PC eine Ewigkeit.

    Wenn dann ein Sleep in so einen Callback eingebaut wird, ist der ganze Prozess am schlafen, was alles andere aufhält => auch die Bearbeitung von Events des Fensters,...

    Deshalb auch das "Not Responding".

    TLDR: Keine Sleeps in Callbacks vom System und nicht zu viel (rechenintensiven) Code in diese Funktionen packen.

  • Hallo Kanashius, hallo Solve-Smart,

    dank für eure Beteiligung. Ich werde das mit dem Sleep testen aber das erklärt ja nicht wirklich das seltsame Verhalten, da es im Code der Hilfe-Datei
    auch drin steht und dort das Fenster eben anders reagiert...

  • Hallo Kanashius,

    habe den Sleep zunächst auf 1 gesetzt = ohne Erfolg.
    nach Löschen des Sleep = ebenfalls kein Erfolg. Gleiches Verhalten wie vor. Nach >5% lässt sich auf einmal
    das Fenster verschieben und dann kommt es zum Fehlverhalten...

    p.s. für einen Hook hat MS ja 4ms als Wert festgelegt. Also müsste schon bei 10ms eigentlich die Progressproc abbrechen...

  • Das was mich wundert ist, das es per default ja ein unverschiebbares Fenster ist (wenn man sich die Parameter in der Hilfe anschaut).

    Die Frage ist, was ändert etwas daran?

    Zeile 46 ist Fehlerhaft: $sDestiUsb = $sPath & "\Test.zip" -> $sDestiUsb = $s_Path & "\Test.zip"

    Btw.: Zeile 20-37, 47,51-53,56,67 kannst du dir meiner Meinung nach sparen
    Zeile 54 sind 300ms und keine 3 Sek. (3000 ms)

    6 Mal editiert, zuletzt von Moombas (16. Mai 2024 um 14:29)

  • Hallo Moombas,

    ich weiss, dass ich die Stick-Erkennung auch via WMI machen kann und damit die "Kontrollstruktur" nicht benötigt würde. ;)
    das mit den ms in Zeile 54 habe ich editiert:thumbup: Nicht das das jemand in den falschen Hals bekommt...

    Deine Verwunderung trifft ja den Kern des Probs. Warum reagiert der Code hier ganz anders als der "gleiche" Code aus der Hilfe...:?:

  • Hier mal meine überarbeitete Variant, schau sie dir mal an:

    6 Mal editiert, zuletzt von Moombas (17. Mai 2024 um 08:40)

  • Den Part habe ich aber quasi untouched (außer der Kürzung immer in der Schleife alle 3 Sekunden die Laufwerke abzufragen, welche von dir kommt) ohne diese vorab zu prüfen und dann ggf. wieder in der Schleife).

    Habe die MSgbox aber mal an die dann richtige Stelle verschoben.

  • p.s. für einen Hook hat MS ja 4ms als Wert festgelegt. Also müsste schon bei 10ms eigentlich die Progressproc abbrechen...

    Hinweis: Das "Sleep()" von AutoIt kann keine kleineren Schritte als 10ms verwenden. Du kannst zum Spaß mal 1000x Sleep(4) laufen lassen und jeweils mit TimerInit & Timerdiff stoppen wie viel Zeit tatsächlich geschlafen wurde. Leider funktionieren auch alternative Methoden wie delayexecution oder nanosleep mit AutoIt nicht zuverlässig (manchmal schon, manchmal aber auch nicht... Zumindest nach meiner Erfahrung).

    Das hilft dir jetzt nicht bei deinem Problem, aber die Info wollte ich loswerden, nicht dass du versuchst "Sleep(4)" anzuwenden und dich dann wunderst was hier eigentlich los ist :D


    lg

    M

  • Hallo Mars,

    danke für deine Erklärung zum Sleep-Befehl. Leider ist aber dieser nicht verantwortlich für das seltsame Verhalten... Ich hatte den Code ja auch ohne diesen getestet
    und das Verhalten war gleich.

  • Ich habe meinen Fehler oben übrigens behoben, ich muss 2mal aus der Schleife springen, das habe ich übersehen.

    Aber dein Problem bleibt leider... und alle meine Tests sind auch im Sande verlaufen. Sobald du während des kopierens es versuchst zu verschieben, hängt es sich auf.

    Einmal editiert, zuletzt von Moombas (17. Mai 2024 um 08:37)

  • Heureka....:klatschen::party:

    Hallo Bugfix, das Keyword Volatile hilft tatsächlich. Das Progressbar-Fenster reagiert damit genau wie der HilfeCode der _WinAPI_CopyFileEx.
    Es bleibt blockiert, lässt sich nicht verschieben und die Progressbar wird dadurch bis zum Ende aktualisiert...

    Hast du evtl. auch eine Erklärung für uns warum das Verhalten auftritt? Wie kann die GUI(ich denke damit meintest du das Progressbarfenster)
    denn den Focus verlieren und weshalb passiert das nicht beim Hilfecode? Liegt es an der Dauer des Kopiervorganges(meine Testdatei ist deutlich größer als die der Hilfe)?

    @ Moombas: Danke für deine Korrektur

  • Hast du evtl. auch eine Erklärung für uns warum das Verhalten auftritt? Wie kann die GUI(ich denke damit meintest du das Progressbarfenster)
    denn den Focus verlieren und weshalb passiert das nicht beim Hilfecode? Liegt es an der Dauer des Kopiervorganges(meine Testdatei ist deutlich größer als die der Hilfe)?

    Ich nehme mal an (weiß es aber nicht definitiv), dass die Callback-Funktion in einem eigenen Prozess läuft, der "empfindlich" auf Störungen reagiert.
    Durch Volatile wird diese Funktion mit einer Art "Schutzschicht" umgeben, sodass sie störungsfrei laufen kann.

    Soweit meine laienhafte Erklärung, aber evtl. kann das jemand noch genauer beleuchten. ;)


    Nachtrag:
    Ich hänge dir mal eine für meinen Job erstellte Kopierfunktion an, vielleicht hilfreich. Musst zum Ausführen nur noch meine "GroupEx.au3" einbinden (oder die betreffenden Passagen auskommentieren).

  • Moin, in der Beschreibung zu Volatile steht:

    Zitat

    Callback Funktion: Während der Ausführung der Funktion wird die Nachrichtenverarbeitung des Skripts nicht blockiert, wie es normalerweise für nicht-volatile Funktionen erfolgt.

    Die Funktion wird damit "von einer Art Schutzschicht" befreit.

    Wenn Du versuchst, das Progressfenster zu bewegen, werden entsprechende Nachrichten an das Skript gesendet. Windows wartet standardmäßig etwa 5 Sekunden darauf, dass diese Nachrichten verarbeitet werden. Das geschieht offenbar nicht rechtzeitig, weil die laufende Callbackfunktion die Nachrichtenbearbeitung verhindert. Nach Ablauf der 5 Sekunden erstellt Windows ein Geisterfenster (eine Bitmap des Fensters mit dem Zusatz "Not Responding") als Ersatz für das nicht reagierende Fenster. Dieses Fenster kann bewegt werden, tut aber sonst nichts.

    Ergänzende Erläuterungen findest Du hier: IsHungAppWindow function

    Man kann das anscheinend auch für den laufenden Prozess abschalten, siehe DisableProcessWindowsGhosting()