2010-12-15 10 views
25

Ich möchte einen Windows-Dienst erstellen, der Daten validiert und von einer anderen Windows-Anwendung darauf zugreift, aber ich bin neu in Diensten und ich bin mir nicht sicher, wie ich anfangen soll.Wie mit einem Windows-Dienst kommunizieren?

Also, während der Dienst läuft, sollte eine Windows-Anwendung irgendwie mit dem Dienst verbinden, einige Daten senden und eine Antwort bekommen, wahr oder falsch.

Antwort

16

Überprüfen Sie IPC tag (Interprocess communications) on StackOverflow. Es gibt eine Reihe von Möglichkeiten und Technologien, um dies zu tun: Windows-Nachrichten, Sockets, MMF und Synchronisationsobjekte, Named Pipes, Mailslots usw.

Als eine der einfachsten Möglichkeiten für diese besondere Aufgabe haben wir unser CBFS IPC Produkt, das kommt mit dem Quellcode.

+2

Link funktioniert nicht, und es scheint nur Werbung – user3800527

+0

@ user3800527 ... und aus diesem Grund hat es viele Stimmen und die Akzeptanz: - \. Vielen Dank für den Kommentar, aber ich habe den Link aktualisiert. –

+0

wählten Sie dann;) – user3800527

3

Sie können dies sehr einfach erreichen, indem Sie den Service als Host für einen WCF-Dienst einrichten und ihn über Ihre Anwendung verbinden.

+0

Dies kann funktionieren, aber es gibt eine Vielzahl von Sicherheitsimplikationen zu berücksichtigen, wenn Sie dies tun. Sie haben jetzt einen Dienst mit offenem Port, der zuhört - wie können Sie überprüfen, wer eine Verbindung herstellt? Sind Sie vor bösartigen Verbindungen geschützt? Möglicherweise müssen Sie die Berechtigungen an NETWORK SERVICE oder an einen anderen Zweck eskalieren, nur um die Verbindung zu öffnen, während Ihr Dienst diese Berechtigungsebene möglicherweise nicht benötigt. Insgesamt - ich würde sorgfältig überlegen, bevor ich dies umsetze, wenn es andere, einfachere und sicherere Optionen gibt. –

+1

@Rob, Sie müssen den Dienst nicht auf einen TCP-Port hören. WCF kann Named Pipes für die Kommunikation zwischen Anwendungen auf demselben Computer verwenden. Natürlich, wenn die Desktop-Anwendung auf einem anderen Computer ist, müssten Sie einen offenen Port haben, aber ich denke nicht, dass das für dieses Szenario der Fall ist. – jlafay

+0

@jlafay - Punkt zu Named Pipes - Sie haben recht, aber für jeden verbindungsorientierten Ansatz werden Sie eine Vielzahl von Sicherheitsimplikationen in Betracht ziehen müssen. –

0

In älteren Windows-Versionen können Sie Ihren Windows-Dienst für die Interaktion mit dem Desktop konfigurieren. Dies ermöglichte es Ihnen, Benutzeroberflächenelemente direkt zu Ihrem Dienst hinzuzufügen, die dem Benutzer präsentiert werden könnten. Ab Windows Vista können Dienste nicht mehr direkt mit Benutzern interagieren, d. H. Keine Benutzeroberflächen.

Um dies zu tun, was Sie tun wollen, ist Ihr Windows-Dienst und eine Front-End-Windows-Anwendung schreiben. Um die Kommunikationsbrücke zwischen den beiden bereitzustellen, würde ich dringend empfehlen, Windows Communication Foundation (WCF) zu verwenden.

Um einen C# -Windows-Dienst zu erstellen, können Sie die Schritt-für-Schritt-Anweisungen here befolgen.

1

Wir verwenden Named Pipes für diesen Zweck. Aber unser Client wurde mit C++ implementiert. Wenn Ihr Dienst und Ihre Anwendung in .Net implementiert sind, können Sie .Net Remoting verwenden.

+1

.NET Remoting wurde von WCF ersetzt. –

+0

@Matt Davis - dass es nicht für alle Remoting-Nutzungsszenarien gilt. Es gibt kein WCF-Äquivalent von binärem Remoting eines MarshalByRefObject-Objekts in WCF (was potentiell die beste Remoting-Lösung für dieses Problem sein könnte). WCF übersteuert Remoting für viele Anwendungsfälle, aber nicht für alle. –

+0

@Matt Davis: Danke für den Kommentar, habe nie mit WCF arbeiten. – DReJ

0

Denken Sie es als Besitzer einer entfernten Datenbank. Angenommen, Sie haben 1 Datenbank noch 10 Anwendungen, die andere Daten aus der Datenbank benötigen, und Sie möchten nicht alle Ihre Daten für jede der Anwendungen öffnen. Auch Ihre Anwendungen werden unabhängig von Ihrer Datenbank sein, Ihre Datenschicht wird nur sein in Ihrem Service implementiert, werden Ihre Anwendungen diese Logik nicht halten. Sie können einen Dienst schreiben und Ihren Dienst für Ihre anderen Anwendungen öffnen.

How to write your first windows service kann Ihnen helfen.

4

Wenn Sie .Net Framework 4 verwenden, bieten Memory-Mapped-Dateien eine relativ einfache Möglichkeit zur Implementierung der Cross-Process-Kommunikation.

Es ist ziemlich einfach und gut in der Dokumentation beschrieben und vermeidet den Overhead (zur Laufzeit, aber auch im Hinblick auf den Entwicklungsaufwand) der WCF oder andere Verbindung/Remoting-basierte Interaktionen oder Schreiben gemeinsamer Daten an einen zentralen Ort und Abfragen (Datenbank, Datei usw.).

Siehe here für einen Überblick.

in Ihrer Klasse: Servicebase, die Service-Klasse darstellt, haben Sie vielleicht:

23

Ich konnte die (fast) gleiche Problem wie Sie Sie wie folgt vorgehen erfolgreich behandeln

public Class() //constructor, to create your log repository 
    { 
     InitializeComponent(); 

     if (!System.Diagnostics.EventLog.SourceExists("YOURSource")) 
     { 
     System.Diagnostics.EventLog.CreateEventSource(
      "YOURSource", "YOURLog"); 
     } 
     eventLog1.Source = "YOURSource"; 
     eventLog1.Log = "YOURLog"; 
    } 

Jetzt, Umsetzung:

protected override void OnStart(string[] args) 
{...} 

UND

benutzerdefinierte behandeln Befehle Anrufe:

protected override void OnCustomCommand(int command) 
    { 
     switch (command) 
     { 
     case 128: 
      eventLog1.WriteEntry("Command " + command + " successfully called."); 
      break; 
     default: 
      break; 
     } 
    } 

Verwenden Sie nun diese in der Anwendung, in der Sie den Windows-Dienst rufen werden:

Enum Ihre Methoden zu verweisen: (denken Sie daran, Dienste Benutzerdefinierte Methoden erhalten immer einen Int32 (128 bis 255) als Parameter und mit Enum machen Sie es einfacher, sich an Ihre Methoden zu erinnern und sie zu steuern

private enum YourMethods 
    { 
    methodX = 128 
    }; 

eine spezifische Methode aufzurufen:

ServiceController sc = new ServiceController("YOURServiceName", Environment.MachineName); 
ServiceControllerPermission scp = new ServiceControllerPermission(ServiceControllerPermissionAccess.Control, Environment.MachineName, "YOURServiceName");//this will grant permission to access the Service 
    scp.Assert(); 
    sc.Refresh(); 

    sc.ExecuteCommand((int)YourMethods.methodX); 

diese Weise können Sie Ihren Dienst steuern.

Here können Sie überprüfen, wie Sie einen Windows-Dienst erstellen und installieren. More über die ExecuteCommand-Methode.

Viel Glück!

+0

keine Notwendigkeit, alles zu fetten, ist da ;-) Bitte bearbeiten – kleopatra

Verwandte Themen