Wie finde ich den HWND, der das Herunterfahren verhindert?

8

Irgendwo in meiner Anwendung (zusammen mit Bibliotheken von Drittanbietern) ist eine Fensterprozedur, die Windows daran hindert:

  • Abmelden
  • heruntergefahren
  • Neustart

Ich habe eine Stelle in meinem Code gefunden, wo ich den außergewöhnlich häufigen Fehler gemacht habe, DefWindowProc aufzurufen, aber falsch zu nennen:

%Vor%

Ich habe diesen Fehler behoben und mein Testprogramm hat das Herunterfahren nicht mehr gestoppt.

Aber eine vollständige Anwendung tut

Ich bin jetzt damit konfrontiert, dass ich ein Programm zu nichts zerreißen muss, bis mein Computer endlich neu startet.

Irgendwo tief in meiner Anwendung befindet sich eine Window-Prozedur, die an eine HWND angehängt ist, die null zu WM_QUERYENDSESSION . Wenn ich nur den HWND kannte, könnte ich den Spy ++ benutzen, um das Fenster zu finden.

Aber wie finde ich das hwnd ?

Im Windows-Ereignisprotokoll Anwendung wird der Prozess protokolliert, der das Herunterfahren anhält:

Und es gibt sehr gut eine detailliertere Anmeldung in den ausführlicheren Anwendungen und Dienste-Logs . Aber diese sind undokumentiert.

Wie kann ich mein problematisches hwnd finden?

Versuche

Ich habe versucht, EnumThreadWindows zu verwenden, um alle Fenster meines "main" -Threads zu erhalten, mit der Idee, WM_QUERYENDSESSION manuell an alle zu senden, um zu sehen, wer false zurückgibt:

%Vor%

Jetzt habe ich eine Liste von zwölf Wochen. Stoßen Sie sie an:

%Vor%

Aber niemand hat Null zurückgegeben.

Das ist also eine Röhre den Bach runter.

    
Ian Boyd 07.02.2017, 16:08
quelle

2 Antworten

3

EnumThreadWindows zählt nur die Fenster eines bestimmten Threads auf. Es könnte sein, dass das betreffende Fenster in einem Thread erstellt wurde. Daher würde ich vorschlagen, dass Sie EnumWindows verwenden, um alle Top-Level-Fenster in Ihrer Anwendung für Ihren Test aufzulisten.

Es ist genug, um COM in einem Thread zu initialisieren, und Sie werden ein Fenster haben, von dem Sie nichts wissen. So könnte ein Aufruf von WaitForSingleObject in einem Thread Ihr Schuldiger sein: Debuggen einer Anwendung, die sich nicht mit WM_QUERYENDSESSION verhält

    
Sebastian Z 08.02.2017, 13:41
quelle
0

Das klingt vielleicht ein wenig nach Overkill, aber hier geht es. Ich würde dies mit Code-Hooks für AllocateHWnd und DeallocateHWnd lösen. Wir mussten ein anderes Problem im Zusammenhang mit Griffen lösen und es hat gut für uns funktioniert.

Ihre Ersatzroutinen sind nur Kopien der Versionen in System.Classes. Sie müssen auch alle Abhängigkeiten ( PObjectInstance, TObjectInstance, CodeBytes, PInstanceBlock, TInstanceBlock, InstBlockList, InstFreeList, StdWndProc, CalcJmpOffset, MakeObjectInstance, FreeObjectInstance, CleanupInstFreeList, GetFreeInstBlockItemCount, ReleaseObjectInstanceBlocks, UtilWindowClass ) von dieser Einheit kopieren. Der einzige Unterschied besteht darin, dass Sie alle zugeordneten und freigegebenen Handles in Ihren Ersetzungsroutinen protokollieren. Es würde helfen, auch Stack-Traces einzubeziehen.

Damit erhalten Sie eine Liste aller Handles, die zum Zeitpunkt des Herunterfahrens zugewiesen wurden, zusammen mit ihren aufrufenden Stack-Traces.

Die Grundstruktur ist so etwas. Ich kann keinen vollständigen Code posten, weil es meistens VCL-Code ist, mit Ausnahme der Code-Hooks und der Protokollierung.

%Vor%

Es kann auch notwendig sein, SetWindowLong, SetWindowLongA und SetWindowLongW ebenfalls zu haken und zu protokollieren.

    
Graymatter 07.02.2017 19:13
quelle

Tags und Links