Fenster aus Service öffnen
-
Hallo alle,
Ich möchte aus einem, von einem Dienst gestarteten, Prozess heraus ein Fenster öffnen. Unter Windows XP ist dies noch relativ gut möglich, in dem bei CreateProcess in der StartupInfo für lpDesktop "winsta0/default" übergeben wird. Ich bin mir zwar ziemlich sicher, dass dies nicht die feine Art ist, aber immerhin hat's getan.
Im Moment läuft dieser Prozess auch noch unter dem lokalen System-Benutzer, also sicherheitstechnisch nicht so toll; dies muss aber nicht zwingend so sein.
Unter Vista erscheint jetzt eine tolle Box und das ganze funktioniert nicht mehr.
Wie mach ich es denn richtig, aus einem so gestarteten Prozess ein Fenster auf dem Desktop des angemeldeten Benutzers zu öffnen?
Zweite Frage: Ist es auch möglich ohne einen angemeldeten Benutzer aus einem solchen Prozess ein Fenster zu öffnen?Danke für die Vorschläge.
-
Nein!
Unter Vista ist dies schon nicht mehr möglich. Du musst einen Prozess starten, der mit Deinem Service kommuniziert und die Meldung auf den Bildschirm bringt.Du weißt eben nicht welchen Desktop ein User hat, der angemeldet ist.
Siehe:
http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/Vista_Services.doc• Services that have a UI, such as a dialog box, cannot display it directly in Windows Vista. Services that require user interaction must handle it indirectly. For simple interactions, services can display a message box in the user's session by calling WTSSendMessage. For more complex interactions, services must use an approach such as calling CreateProcessAsUser to create a UI process in the user's session. That process handles user interaction and communicates with the service through RPC or named pipes.
For further information about Session 0 in Windows Vista and guidelines for writing Windows Vista services, see the white paper titled Impact of Session 0 Isolation on Services and Drivers in Windows Vista, which is listed in "Resources" at the end of this paper.
-
Ich habe mich jetzt auch noch ein bisschen informiert.
Mir ist schon klar, dass der Dienst selber nichts auf den Desktop pinseln kann. Daher habe ich ja bereits einen zweiten Prozess und eine Kommunikation über SharedMemory.
Mittlerweile habe ich auch ein paar Funktionen gefunden, mit denen es möglich sein sollte, einen Prozess im Namen des angemeldeten Benutzers (falls vorhanden) zu starten. Diese Funktionen sind WTSQueryUserToken und WTSGetActiveConsoleSessionId.
-
Ich hab jetzt alles hinbekommen. Falls es jemand interessiert:
- Mit WTSGetActiveConsoleSessionId und WTSQueryUserToken auf einen angemeldeten Benutzer warten
- Mit CreateProcessAsUser den neuen Prozess starten
- SharedMemory vom Dienst aus öffnen, dabei einen entsprechenden SecurityDescriptor übergeben; damit darf der Anwenderprozess dann darauf zugreifen
- Beim Öffnen des SharedMemory vom Anwenderprozess darauf achten, dass das SharedMemory (normalerweise) im Global-Namespace liegt (zumindest unter Vista); d.h. OpenFileMapping mit "Global\"-PräfixDanach können die zwei Prozesse dann einfach miteinander reden

-
WTSQueryUserToken funktioniert aber erst ab Windows Vista, oder?
Dein Programm wäre also unter WinXP nicht mehr lauffähig.
Wenn doch, dann wäre ich für ein Posting des Quellcodes dankbar.