Entwickler-Ecke

Windows API - Meldung via externe Exe/RunDll


delfiphan - Do 22.05.08 22:57
Titel: Meldung via externe Exe/RunDll
Hallo

Ich möchte gerne über ShellExecute eine Meldung ausgeben (wenn möglich mtInformation Typ wie bei MessageDlg).

Ich möchte so eine Meldung anzeigen, kurz bevor sich das Programm schliesst und die Meldung sollte nach dem Beenden stehen bleiben. Eine eigene Exe für die Meldung zu programmieren kommt leider nicht in Frage. Wieso es genau so sein muss ist erst mal irrelevant.

Ich denke, das müsste per RunDll und irgend einer Windows DLL eigentlich gehen. Die Lösung kann auch ganz anders aussehen, auch ohne ShellExecute. Die Meldung muss einfach nach dem Beenden bleiben.

Kann mir da jemand helfen oder kreativen Input geben? :)

Danke!
delfiphan


Magic J - Fr 23.05.08 02:18

Hi,

also ich hab da grad aus eigenem Interesse etwas rumprobiert:

Also die Funktion "MessageDlg" kommt ja direkt aus der Unit "Dialogs" und es liegen keine DLL´s zu Grunde. :?

Als einzige Message-Function, die aus einer DLL stammt, konnte ich nur "MessageBox" aus "user32.dll" ausfindig machen!


Mit einige Versuchen kam ich hierzu: :idea:

Delphi-Quelltext
1:
  ShellExecute(handle,'open','rundll32.exe',Pchar('user32.dll, MessageBoxA Hallo'),'',SW_show);                    


Damit wird schonmal ein Fenster erzeugt, dass unabhängig vom Programm läuft und somit nach dem Beenden bestehen bleibt!
Allerdings:

Bisher wird das "Hallo" in die Kopfzeile geschrieben und im Feld stehen unverständliche Zeichen...
Ausserdem werden die Button "Wiederholen" und Abbrechen" angezeigt.

Du wirst also noch weiter probieren dürfen, welches PChar in "Parameters" zu einem gewünschter Ergebnis führt!

Bei Erfolg, bitte melden! :wink:
Gruß, Jonas


delfiphan - Fr 23.05.08 08:25

Danke. An sowas hatte ich auch gedacht.

Ich kriege aber wie du die weiteren Parameter nicht rein. Da müsste man die eigentliche Nachricht und den MessageTyp noch setzen können.


Magic J - Fr 23.05.08 18:14

Hi,

tja, also wenn man das mit anderen Funktionen macht, dann muss man die Parameter nur mit einem Komma von einnander trennen.
Das geht hier ja leider nicht, denn er schreibt ja, egal was, alles in die Kopfzeile.

Habs auch schon mit nem #0 probiert, da PChar´s ja damit terminiert werden:

Delphi-Quelltext
1:
ShellExecute(handle,'open','rundll32.exe',Pchar('user32.dll, MessageBoxA Caption'+#0+'Text'),'',SW_show);                    

Aber da ist das "Text" dann ganz verschwunden.


Das mit dem "MessageTyp" kannst du hier ja sowieso vergessen!

Wenn du in der Unit "Windows" mal schaust:

Delphi-Quelltext
1:
function MessageBoxA(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): Integer; stdcall;                    


Anderst als bei "MessageDlg" gibts hier keinen Parameter dafür!


Gruß, Jonas


delfiphan - Fr 23.05.08 22:42

Naja, uType wäre dafür gedacht (Message-Typ). Hat jemand vielleicht noch eine ganz andere Idee? Mit RunDll scheint es ja offensichtlich nicht zu gehen. Kann man vielleicht von Delphi aus einen neuen Prozess erzeugen und dort die MessageBoxA laufen lassen?


Magic J - Sa 24.05.08 10:47

Zitat:

Naja, uType wäre dafür gedacht (Message-Typ)


Nee, "uType" ist doch nur für die Auswahl der buttons zuständig.


delfiphan - Sa 24.05.08 11:55

user profile iconMagic J hat folgendes geschrieben:
Zitat:

Naja, uType wäre dafür gedacht (Message-Typ)


Nee, "uType" ist doch nur für die Auswahl der buttons zuständig.
uType bestimmt die dargestellten Knöpfe, den Default-Knopf, Icon, Modalität und weitere Optionen. Siehe MSDN [http://msdn.microsoft.com/en-us/library/ms645505(VS.85).aspx].

Ist es denn unmöglich, eine solche Meldung in Windows anzuzeigen? :shock:


Silas - Sa 24.05.08 13:42

Moin delfiphan,

ich hätte da eine Idee, weiß aber nicht ob das funktioniert (sollte es aber, so wie ich die API kenne): Du könntest ein zusätzliches Programm für die Box schreiben, dann das Programm (binär) als Ressource einbinden, bei Gebrauch in eine named Pipe schreiben und die anschließend CreateProcess als Filename-Parameter übergeben. Wie gesagt, nur eine Idee.


delfiphan - So 25.05.08 22:06

Nun ja, wie geschrieben, eine separate Exe will ich eigentlich nicht mitliefern bzw. mitschmuggeln.

Hat jemand sonst noch eine Idee, wie ich eine Meldung machen kann, die nach Programmende bestehen bleibt?


Delete - Mo 26.05.08 09:21

Warum muss denn die Meldung nach Beendigung des Programmes noch angezeigt werden? Und ohne separates Programm wird das wohl nicht gehen. Das eine schließt das andere aus. Du wirst dich wohl entscheiden müssen, entweder separates Programm oder keine Meldung.


delfiphan - Mo 26.05.08 20:58

Separates Programm ja, aber nicht ein von mir geschriebenes sondern mit Windows-Mitteln. RunDll32 wäre eine Lösung gewesen, wenn diese korrekt funktioniert hätte. Separates eigenes Programm geht nicht, wenn das ganze auf einem Transfer-Share liegt - wegen Windows Sicherheitseinstellungen.

Es geht darum, dass ich das Schliessen aller Instanzen im Netzwerk erzwingen kann (das geschieht mittels eines entsprechenden Befehls über die DB-Verbindung), in diesem Fall jedoch mindestens noch eine Meldung hinterlassen will. Es kommt natürlich einige Zeit vorher eine "richtige" Warnung während das Programm läuft; aber nachdem man es "abgeschossen" hat, sieht man jedoch den Grund des Verschwindens nicht mehr. Da momentan die Rahmenbedingungen so sind, dass das Programm auf dem Transfer-Share liegt, müssen alle Instanzen geschlossen sein, damit ich die Exe für ein Update überschreiben kann.


Chryzler - Mo 26.05.08 21:31

Naja, man könnte per CreateRemoteThread den MessageBox-Aufruf in nem anderen Prozess aufrufen, allerdings brauchst dann irgendeinen Prozess der sicher auf jeder Maschine läuft. Wenn der beendet wird, ist die Meldung dann natürlich auch weg. Weiß nicht ob dir das zusagt.


delfiphan - Di 27.05.08 11:01

In welchem "anderen Prozess?"


Delete - Di 27.05.08 11:56

Wo ist der Unterschied, ob du dir nun einen mit der rundll abbrichst oder schnell ein eigenes Programm mit Shellexecute startest?


delfiphan - Di 27.05.08 15:33

Ich kann mit ShellExecute kein Programm ausführen, das auf einem Share liegt. Ist wohl ein Windows Security Feature - beim manuellen Ausführen kommt ja ein Dialog, ob ich die Exe nun wirklich ausführen will, über ShellExecute passiert einfach nichts. Vielleicht weisst du ja, wie/ob ich das umgehen kann.
Wie gesagt liegt das Projekt auf einem Share und wird über den UNC Pfad aufgerufen.