C # Ausführen der Windows Form-Anwendung vom Dienst (und in Vista)

7

Ich schreibe eine Anwendung in C #, die als Dienst ausgeführt werden muss, aber auch über Benutzerinteraktion verfügt. Ich verstehe, dass Dienste keine UI usw. haben, also habe ich mein Programm in eine Windows-Formularanwendung und einen Dienst aufgeteilt, die miteinander kommunizieren können.

Das Problem, das ich habe, ist, dass ich den Dienst brauche, um sicherzustellen, dass die Windows-Formularanwendung immer ausgeführt wird, und starte sie neu, wenn dies nicht der Fall ist. Ich kann feststellen, ob es läuft, und starte es mit dem folgenden Code unter Windows 2000 / XP:

%Vor%

Aber unter Vista wird der neue Prozess als lokaler / Systemprozess ausgeführt, der für den Benutzer unsichtbar ist. Geht das jemand anders herum? Gibt es eine Möglichkeit zu erkennen, welcher Benutzer gerade angemeldet ist und den neuen Prozess als diesen Benutzer ausführen? Ich muss an dieser Stelle nicht den schnellen Benutzerwechsel berücksichtigen. Etwas - irgendetwas - Grundlegendes würde genügen.

Ich wäre dankbar für jede Hilfe oder Tipps, die Sie zu diesem Thema haben.

Ich muss klarstellen, dass ich die Option "Dienst mit Desktop interagieren" bei der Installation des Dienstes festlegen möchte. Dies ermöglicht es, auf 2000 / XP zu arbeiten. Vista hat jedoch immer noch das vorgenannte Problem.

    
Andrew Ensley 06.01.2009, 20:55
quelle

8 Antworten

13

Die allgemeine Idee für diese Art von Dingen ist, wenn der Benutzer mit einem Dienst interagieren soll, sollten sie eine separate Anwendung starten. Wenn Sie ihnen helfen möchten, können Sie diese separate Anwendung so konfigurieren, dass sie mit Windows beginnt, indem Sie im Startmenü eine Verknüpfung einfügen. Sie können die Wiederherstellung nach einem Absturz auch in Ihrer Anwendung erstellen, sodass sie automatisch neu gestartet werden kann.

Sie sollten sich nicht wirklich darauf verlassen, die Formularanwendung zu überwachen, was ist, wenn niemand eingeloggt ist? Was passiert, wenn mehrere Personen angemeldet sind? Es wird einfach unordentlich, Dinge auf diese Weise zu tun.

Den Service einfach dort sitzen zu lassen und an Zuhörer zu senden, ist der Weg zu gehen. Wenn die Formularanwendung gestartet wird, kann sie den Dienst benachrichtigen, der auf Ereignisse warten möchte.

    
Bob 06.01.2009, 21:07
quelle
3

Siehe die Frage: Wie kann ein Windows-Dienst eine ausführen? GUI-Anwendung? . Es adressiert die gleiche Frage von C / C ++ (kurze Antwort: CreateProcessAsUser), aber die Antwort ist immer noch gültig (mit einigen P / Invoke) für C #.

    
Roger Lipscombe 06.01.2009 22:04
quelle
2

In diesem Fall müssen Sie einen dritten Monitorprozess haben, der feststellt, ob das Programm fehlschlägt, und es in diesem Fall neu starten.

Allerdings haben Sie hier ein unlösbares Problem, da der Überwachungsprozess überwacht werden muss, um sicherzustellen, dass er nicht heruntergefahren wird, und so weiter und so weiter.

Vielleicht möchten Sie diesen Ansatz noch einmal überdenken.

    
casperOne 06.01.2009 20:58
quelle
1

Es ist eine schwierige Situation. Wie an einigen Stellen erwähnt, sollten Sie, wenn Sie müssen eine Benutzeroberfläche haben, technisch gesehen keinen Dienst verwenden. Afterall, Dienste laufen, ohne dass ein Benutzer sich sogar anmeldet. Wenn niemand eingeloggt ist, können Sie keine Benutzeroberfläche haben.

Normalerweise, wenn ich brauche, dass ein Dienst mit der Außenwelt kommunizieren muss, gibt es zwei Dinge, für die ich mich entscheide. Ich kann entweder einen Eintrag in das Ereignisprotokoll schreiben oder eine Nachricht in eine Warteschlange einfügen.

In Ihrem Fall würde ich eine Warteschlange verwenden. Wenn sich ein Benutzer anmeldet, können Sie automatisch eine App für sie starten, die die Warteschlange überwacht. Wenn die App ausgeführt wird, werden sie beim Empfang der Nachricht ebenfalls auf diese Weise benachrichtigt. Wenn der Benutzer die App jedoch schließt, passiert das Gleiche ... sie werden es nicht wissen.

    
Sailing Judo 06.01.2009 21:27
quelle
1

Zunächst eine schnelle Antwort: Erlaubt die Option "Dienst mit Desktop interagieren" (Dienst - & gt; Eigenschaften - & gt; LogOn) oder die Angabe eines Kontos was Sie wollen? Wenn dies der Fall ist, können beide in Ihrer Service-Installer-Klasse konfiguriert werden.

Wie die anderen vermute ich, dass es einen besseren Ansatz dafür gibt und einer der folgenden Punkte zutrifft: -Der Code innerhalb des Dienstes könnte in der Winforms-App enthalten sein (möglicherweise in einem Hintergrundthread) und dem Windows-Start hinzugefügt werden. Beide werden laufen -Die Winforms-App kann den Dienst nur abhören, wenn er eingeschaltet ist, und muss nicht über den Dienst gestartet werden. Oder ähnlich könnte die App zum Start hinzugefügt werden.

    
Daniel 06.01.2009 21:36
quelle
1

Damit Ihr Dienst die Anwendung als Benutzer ausführen kann (was anscheinend das ist, was Sie zu tun versuchen), müssen Sie Folgendes tun:

%Vor%

Wo:

  • Pfad = vollständiger Pfad (einschließlich Dateiname) der ausführbaren Datei.
  • Argumente = String von Argumenten (verwenden Sie einen leeren String ist keiner)
  • username = Der Name eines Benutzerkontos auf Ihrem Server / Computer
  • domain = Ihre Netzwerkdomäne (wenn Sie ein Netzwerkkonto verwenden - leer, wenn keines vorhanden ist)

Damit Ihr Dienst die Berechtigung zum Starten einer Anwendung hat, muss er auch als Dienst ausgeführt werden. Um dies zu tun, müssen Sie diese Zeilen zu Ihrer Service-Installer-Klasse hinzufügen:

%Vor%     
Tyson Zwicker 20.04.2010 19:22
quelle
0

In Windows 2000 und XP gibt es eine Option (Kontrollkästchen) auf der Registerkarte Anmelden des Diensteigenschaftenfensters, damit der Dienst mit dem Desktop interagieren kann. Ich glaube, das ist es wonach Sie suchen. Ich habe gerade einen schnellen Dienst in VB.NET mit einem Process.Start ("calc.exe") und einem Windows-Rechner geschrieben, der gerade gut geöffnet wurde.

Ich bin nicht 100% sicher, dass dies in Vista genauso funktioniert.

    
Rich 06.01.2009 21:20
quelle
0

Klingt so, als ob Sie nicht die Hälfte davon als Dienst ausführen müssten (es sei denn, Sie benötigen höhere Privilegien), da Ihr Dienst damit zurechtkommen müsste, wenn auch kein interaktiver Benutzer angemeldet ist.

    
Rowland Shaw 06.01.2009 21:23
quelle