2010-02-11 5 views
11

Ich habe einen Windows-Dienst geschrieben, von dem ich 1 Instanz pro Kunde ausführen lassen möchte. Dies liegt daran, dass die Kunden jeweils ihre eigene DB mit identischen Schemas haben; Der einzige Unterschied zwischen den Windows-Diensten besteht darin, dass sie jeweils einen anderen Parameter haben, der dem Kunden-DB entspricht, für dessen Zustellung sie bestimmt sind. (Und ich kann keinen Dienst mit mehreren Worker-Threads haben, weil die DB-Verbindung eine statische Variable verwendet, über die ich nicht über Threads hinweg fiedeln kann.)Wie mache ich einen Windows-Dienst mit Parametern?

Ich habe this neat little tutorial darüber gefunden, wie man einen Windows-Dienst macht, aber es zeigt mir nur, wie man es für einen einzelnen Dienst aufstellt. Ich möchte n Instanzen des Dienstes einrichten, jeder mit einem Anzeigenamen, der den Kundenname enthält, der mit dem Befehlszeilenparameter ausgeführt wird, der die Kundenid bezeichnet.

Die verlinkte Tutorial oben hat eine Klasse MyWindowsServiceInstaller genannt, die den Windows-Dienst auf dem lokalen System installiert, und ich vermute, dass dies ein logischer Ort sein würde, eine foreach Schleife durch alle meine Kunden einzurichten, einen Dienst einrichten für jede. Aber ich kann nirgendwo auf den bereitgestellten Schnittstellen sehen, dass ich einen Befehlszeilenparameter für den neuen Dienst einrichten konnte.

Wie machst du das?

+0

ich meine Antwort bin zu entfernen, da die Leute ist, dass über diese wissen, dass es mehr als mich. –

+0

@Binary Worrier - Ich wünschte, du hättest deine Antwort nicht entfernt! Da waren einige Ideen drin, die sehr vielversprechend waren ... –

+0

Antwort unletted: Ich habe es als CW markiert, es ist unvollständig, wir haben einen Spickzettel irgendwo mit "How to" Anweisungen, um mehrere Instanzen des gleichen Dienstes zu bekommen, aber Ich kann es nicht finden und habe keine Zeit zu graben, sorry Shaul. –

Antwort

7

Wil Peck wrote a good article darüber, wie mehrere Instanzen von Windows-Dienst auf einer einzigen Box zu installieren.Die Grundidee ist, dass Sie das Installationsprogramm dazu bringen müssen, verschiedene Dienste zu denken, indem Sie ihnen unterschiedliche Namen geben.

Nachdem dies gesagt wurde, scheint es einfacher (und wartungsfreundlicher) zu sein, Ihren Datenbankverbindungscode neu zu gestalten, so dass er mehrere Worker-Threads unterstützen kann.

+1

+1 für den Link, +1 erneut, wenn ich für den Rat mehrere Works-Threads in einem Dienst haben könnte. Sie können jederzeit eine grafische Benutzeroberfläche für den Dienst bereitstellen und Informationen zu den laufenden Threads anzeigen. –

+0

Yup, Wil hat die Antwort. Vielen Dank für den Zeiger! –

1

Sie müssen den Dienst im Grunde mehrmals installieren und mit seiner exe.config-Datei anpassen.

Alternativ können Sie einen Dienst verwenden, der verschiedene Arbeitsthreads für jeden Client ausführt.

aktualisieren

exe.Config ist ein Application Configuration File

ich keine Ahnung, wie diese Installer-Komponente verwenden mehrere Instanzen des Dienstes zu installieren, ich konnte man sich nicht bewusst war.

Wenn mehrere Instanzen eines unserer Services auf einem Computer ausgeführt werden müssen, wird dieser tatsächlich nur einmal installiert. Anschließend wird der installierte Ordner kopiert und der exe-Name für das zweite Exemplar geändert. Die zweite Instanz wird dann in ihrer eigenen Anwendungskonfigurationsdatei konfiguriert.

+0

In dem Tutorial, das ich oben verlinkt habe, gibt es eine Klasse namens MyWindowsServiceInstaller, die die Installation durchführt. Es sieht so aus, als sollte das der Ort sein, an dem eine Schleife für alle Kunden eingerichtet werden soll - aber ich kann überhaupt nirgends sehen, wie ich die Befehlszeilenparameter für jeden Dienst einstelle. Wie richten Sie die Parameter ein? und verzeihe meine Unwissenheit, aber was ist exe.config? –

+0

habe meine Frage aktualisiert, um einige der von Ihnen erwähnten Punkte zu klären. –

+0

+1 für den Link zur App Config-Datei –

1

Soweit ich weiß, ist es unmöglich, Startparameter unter Verwendung entweder ServiceInstaller, ServiceProcessInstaller oder installutil bereitzustellen. Es ist jedoch möglich, Startparameter unter Verwendung einiger COM-APIs von advapi.dll bereitzustellen (siehe das linke Menü). Eine vollständige Sammlung der erforderlichen Anrufe finden Sie unter here. Es ist eine Klasse (auch) ServiceInstaller, die die erforderlichen externen Methoden und einige Hilfsmethoden enthält.

Sie möchten die Hilfsmethode InstallAndStart verwenden. Er akzeptiert einen Dienstnamen, einen Anzeigenamen und einen Pfad zu der ausführbaren Datei, die Ihren Windows-Dienst darstellt. Sie können es so nennen:

InstallAndStart("MyService", "My Service For User 1", 
       "c:\\pathtoexe\MyService.exe user1"); 

Wenn Sie den folgenden Dienst haben die Parameter startupParamuser1 den Wert erhalten.

class Program : ServiceBase 
{ 
    private string startupParam; 

    static void Main(string[] args) 
    { 
     string arg = args[0]; 
     ServiceBase.Run(new Program(arg)); 
    } 

    public Program(string startupParam) 
    { 
     this.ServiceName = "MyService"; 
     this.startupParam = startupParam; 
    } 
    ... 
} 
+0

ummm ... habe gerade versucht, und es sieht nicht aus wie installutil können Sie Parameter übergeben ...? Fehle ich etwas? –

+0

Hm, scheint ich nicht richtig zu sein. Sorry dafür und vergiss den Installutil-Teil. Ich verwende selbst eine benutzerdefinierte ServiceInstaller-Klasse, die COM-APIs zum Starten und Stoppen von Diensten verwendet. Diese Klasse erlaubt das Übergeben von Parametern und ich dachte, installutil würde das Gleiche tun. Ich werde meine Antwort aktualisieren ... –

+0

Ronald, ich habe einen Client, der den Windows-Dienst benötigt, um Aktionen auf dem System mit dem Systemkonto auszuführen, da mein Client keine Berechtigungen hat. Wenn ich möchte, dass der Client dem Windows-Dienst mitteilt, was zu tun ist, sollte ich jedes Mal anhalten und neu starten, indem ich solche Argumente übergebe? Ich habe die OnCustomCommand-Funktion gefunden, die jedoch nicht sinnvoll ist, da Sie nur Ganzzahlen übergeben können. Oder sollte ich eine Datenbank oder Registrierungsschlüssel verwenden, um basierend auf dem ausgeführten Client vorübergehend Argumente festzulegen? – MacGyver

-2

Wenn die Verwendung von Drittanbieter-Tools in Ordnung ist, versuchen Sie http://installer.codeeffects.com. Mit ihnen können Sie ein .exe-Installationsprogramm für Ihren Windows-Dienst erstellen und der Benutzeroberfläche des Installationsprogramms Parameter hinzufügen. Außerdem müssen Sie kein eigenes Setup-Projekt entwickeln. Hoffe das hilft.

+0

$ ping installer.codeeffects.com ping: kann installer.codeeffects.com nicht auflösen: Unbekannter Host – harperville

12

Alles, was ich wollte, war, einen Parameter an den Service zu senden, den ich erstellt habe. Wie Sie sehen, müssen Sie (vorsichtig!) Die Registrierung unter HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ bearbeiten und nach den Anführungszeichen den Parameter in ImagePath hinzufügen.

Eg. ImagePath Wert: „C: \ Programme \ myservice \ MyService.exe“ param1

fand ich die Lösung in diesem Link http://social.msdn.microsoft.com/Forums/is/csharpgeneral/thread/38242afa-7e40-4c06-975e-aa97d3cc782f