Shellexecute und der Rückgabewert HInstance


Immer wieder kommt es vor, dass jemand mit Shellexecute ein Programm startet und dann versucht, mit dem von Shellexecute zurückgegebenen Wert, das Fenster dieses Programmes zu schließen oder versucht auf die Beendigung dieses Prozess zu warten, was aber nicht klappt.

Shellexecute gibt einen Wert vom Typ HINSTANCE zurück. Unter Delphi entspricht das einem LongWord bzw. einem Cardinal. Unter 16-Bit Windows hat HInstance ein Prozess identifiziert in dem es der Basisadresse entsprach, an der der Prozess im Speicher geladen wurde. Unter 32-Bit Windows wurde aber der Kernel komplett neu geschrieben und es wurden Konzepte wie "Kernel Objekte" und "Sicherheitsbeschreiber" eingeführt. Insbesondere kannte 16-Bit Windows keine ProzessIDs. Deswegen geben WinExec und Shellexecute eine HInstance zurück. Da unter 32-Bit Windows jeder Prozess in seinem eigenen Adressraum läuft und HInstance der Basisadresse entspricht, an die ein Prozess geladen wurde (Die in den meisten Fällen 0x00400000 sein wird, da dies die standard Adresse ist, an der ein Prozess geladen wird.), kann man damit natürlich einen Prozess nicht mehr eindeutig identifizieren.

Also was kann man mit den Rückgabewert anfangen? Eigentlich nichts außer zu überprüfen, ob er größer als 32 ist, was bedeutet, dass der Aufruf erfolgreich war bzw. wenn er kleiner als 32 ist, entspricht der Wert einen Fehlercode, den man auswerten kann.

Dies alles kann man natürlich auch im PSDK nachlesen, aber irgendwie scheint niemand so richtig zu lesen, was da interessantes zu dem Rückgabewert steht:

The return value is cast as an HINSTANCE for backward compatibility with 16-bit Windows applications. It is not a true HINSTANCE, however. The only thing that can be done with the returned HINSTANCE is to cast it to an int and compare it with the value 32 or one of the error codes below.

Brauch man die ProzessID oder den Handle des Prozesses, dann muss man entweder auf die API-Funktion ShellexecuteEx oder CreateProcess zurückgreifen.

Delphi implementierung von ShellexecuteEx: Warten auf Ende des Child-Process - OHNE CreateProcess() (Aus der Code-Library der Delphipraxis).

2010-12-29T23:44:54 +0100, mail+homepage[at]michael-puff.de