![]() |
SendMessage durch Fremdprogramm blockiert
Hallo zusammen,
ich bin gerade über etwas seltsames gestossen. In meinem Programm verwende ich folgenden Code:
Delphi-Quellcode:
wobei WM_TESTXYZ
if SendMessage(wnd, WM_TESTXYZ, 0, GetCurrentProcessId) = 2 then
begin //irgendetwas tun end;
Delphi-Quellcode:
normalerweise funktioniert das wunderbar. Habe ich aber nun das Tool
const
WM_TESTXYZ = WM_APP + 100; ![]() geöffnet, so blockiert mein Programm bei dem oben genannten Aufruf. Hat hier jemand eine Idee wie man das umgehen kann? Ist es tatsächlich so das dieses Tool meine Messages blockiert? :gruebel: Gruss und Danke |
Re: SendMessage durch Fremdprogramm blockiert
Wenn solche Programme ebenfalls WM_APP + 100 verwenden und per Hooking sich in deine Nachrichtenschleife hängen kann sowas leicht passieren. Wir hatten oft Probleme mit NVidia Desktop Manager. Und da war es definitiv schlecht von NVidia programmirt da selbst der Windows Explorer sich öfters aufgehängt hat wenn dieser aktiv war.
|
Re: SendMessage durch Fremdprogramm blockiert
Hallo,
ich habe auch schon diverse andere "WM_APP" versucht... +100 - +1024...alles wird blockiert. Aber es sieht wirklich so aus als leite dieses Tool die Meldungen nicht mehr korrekt weiter :( Danke trotzdem für Deine Antwort :thumb: Gruss |
Re: SendMessage durch Fremdprogramm blockiert
Guck doch mal was für DLLs bei dem Ding dabei sind. Wenn da eine der DLLs die folgenden Funktionen aus User32.dll importiert, ist vermutlich der Autor des Tools schuld:
SetWindowsHookEx, SetWindowsHook, UnhookWindowsHookEx oder UnhookWindowsHook Kann auch sein, daß er die dynamisch importiert. Dann hilft dir nur Reverse Engineering ;) |
Re: SendMessage durch Fremdprogramm blockiert
Vielleicht solltest du
wm_User + XYZ benutzen. Und statt SendMessage() eventuell SendMessageTimeout() benutzen, besonders falls das Fenster Wnd in einem anderen Thread oder Process erzeugt wurde. Um solche Kollisionen zu vermeiden kann man auch global mit RegisterWindowMesage() eine eindeutige MessageID registrieren. Die darf dann NICHT durch andere Programme blockiert werden, wenn doch sind diese ein Fall für den Mülleimer ! Gruß Hagen |
Re: SendMessage durch Fremdprogramm blockiert
Zitat:
![]() |
Re: SendMessage durch Fremdprogramm blockiert
@Olli
im Dependency Walker werden die von Dir genannten DLL's nicht angezeigt |
Re: SendMessage durch Fremdprogramm blockiert
Liste der Anhänge anzeigen (Anzahl: 1)
@negaH
im ursprünglichen Source Code wurde die Message auch mit "RegisterWindowMesage()" registriert (siehe Source Code im Anhang), aber auch dies hat nicht funktioniert. Im Debugger komm ich bis auf Zeile 134...
Delphi-Quellcode:
...bei der dann meine Applikation hängen bleibt.
if SendMessage(wnd, WM_DELPHIAPPCOMMUNICATION, 0, GetCurrentProcessId) = 2 then
Kann man damit eindeutig sagen das dieser Pixel Ruler die Ursache für dieses Problem ist? Wenn ich den Pixel Ruler Prozess (mioengine.exe) wieder beende, läuft alles wieder wunderbar. Gruss |
Re: SendMessage durch Fremdprogramm blockiert
Ja kann man annehmen. Allerdings muß der Programmierer dieser Sofwtare nicht schuld sein. Dh. er hat sich zb. an die MS Spezifikationen der Hooks gehalten und erst im Zusammenhang mit noch anderen DLL/Prozessen/Treibern entsteht dieses Problem.
Frage: das Wnd ist ein Fensterhandle aus deiner Anwendung ? Falls ja ist definitiv was falsch. Falls nein so besteht die Möglichkeit das du mit dem Aufruf von SendMessage() an ein Fensterhandle eines anderen Prozesses einen Fehler machst. Dazu muß man weiter ausholen: Microsoft empfiehlt bei "Interprozesskommunikation" SendMessage() nicht zu benutzen. Falls Wnd aus einem anderen Prozess stammt dann ist dies eine Interprozesskommunikation. SendMessage() kehrt per Definition erst dann zurück wenn der Fensterhandler -> WndProc des empfangenden Fensters auzurückkehrt. In dieser Zeitspanne blockiert SendMesage() unseren Prozess, bzw. genau gesagt unseren Messagequeue. Nun hookt sich das Fremdprogram überall dazwischen. Bei jeder Nachricht informiert der globale Hook dieses Programmes seinen eigenen Kernel. Also alle Nachrichten aller Fenstern im System werden abgefangen und wahrscheinlich informieren die "Hooks" ihren Mutterprozess. Dieser reagiert nun seinerseits darauf indem er zb. wm_GetText des aktiven Fensters unserer Applikation aufrufen möchte. Das macht er per SendMessage(). Da unser Prozess immer noch in seiner SendMessage() ist die intern im System gerade im Hook ist, der seinen Mutterprozess ebenfalls per SendMessage() informiert, der daraufhin selber mit SendMesages() eines unsere Fenster ansprechen möchte, das aber in der eigenen SendMessage() noch hängt, haben wie einen typischen Deadlock. Das passierte weil zwei Programierer einen Denbkfehler gemacht haben. 1.) der Entwickler von PixelRuler benutzt SendMessage() für Interprozesskommunikation obwohl er SendMessageTimeOut() benutzen müsste 2.) der Entwickler deines Programmes, also DU, benutzt SendMessage() für Interprozesskommunikation obwohl er SendMessageTimeOut() benutzen müsste Einer von beiden MUSS SendMessageTimeout() benutzen damit dieser Deadlock beseitigt wird. Normalerweise derjenige der den Hook implementiert, meine ich, aber ich persönlich würde denoch an deiner Stelle nie SendMessage() benutzen, einfach um sicherzugehen. Oben schrieb ich "informieren die Hooks ihren Mutterprozess". Einen globalen systemweiten Hook gibt es im Grunde garnicht, das ist in einem Protected Mode OS garnicht möglich (mal abgesehen von Kernelhooks sprich auf Ring 0 in Treibern). Ein globaler Hook besteht nämlich aus X prozesslokalen Hook-kopien die jede für sich gesehen in den Addressraum aller betroffenen Prozesse im gesammten System injeziert werden (durch das OS selber). Das bedeutet das die Hookprocedure der Hook-DLL quasi 1 gemeinsammes Codesegment für alle Prozesse benutzt aber X verschiedene eigene Datensegemente, für jeden gehookten Prozess, ein eigenes. Dies führt nun dazu das der Hookprogramierer mit seinem Mutterprozess kommunizieren muß. Man benötigt eine Interprozesskommunikation. Naiv betrachtet benutzt ein unerfahrerener Programmierer nun die SendMessage() Funktion um eigene Steuernachrichten aus dem Hook heraus an seinen Mutterprozess zu senden. So das wäre EIN Szenario. Ein weiteres ist es das Wnd garkein gültiges Fensterhandle mehr enthält. Hm, SendMessage() müsste eigentlich daraufhin sofort zurückkehren. Allerdings wenn Wnd ein Fensterhandle enthält das zwar noch gültig aber tot ist, sprich blockiert, deadsubclassed etc.pp. dann kann SendMessage() dieses nicht erkennen. Sie ruft die WndProc dieses Fensters auf und diese Callback kehrt nie zurück oder der Aufruf landet im Nirvana. Aber auch hier hilft SendMessageTimeout(). Gruß Hagen |
Re: SendMessage durch Fremdprogramm blockiert
@negaH
Danke für Deine ausführlichen Erklärungen. Die Erklärung für das Verhalten war wie von Dir richtig erkannt der "SendMessage Deadlock". Zitat:
Wenn jeweils nur ein Entwickler die "SendMessage" Funktion verwenden würd, dann gäbes es keine solchen Probleme. Wenn man allerdings sauber programmieren will, darf man wirklich nicht von solchen Annahmen ausgehen. Und wieder habe ich was dazu gelernt :dancer: Ich habe nun sämtliche "SendMessage" Aufrufe mit "SendMessageTimeout" ersetzt, seither läuft alles wie geschmiert :hello: Danke für die super Unterstützung, Gruss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:29 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz