michi.wtr
Goto Top

Windows Service erstellen

Hey zusammen,

Ich habe mir überlegt, einen eigenen Service für einen Server zu schreiben, der mich informieren soll, sobald eine Datei unter einem bestimmten Pfad geändert wird. Dafür habe ich folgenden PS Script gefunden:

File Monitoring - PowerShell
Kurzfassung:
In einer Dauerschleife wird mittels System.IO.FileSystemWatcher ein Pfad mit bestimmten Kriterien überwacht (Änderung der Datei, erstellen von Dateien, löschen von Dateien etc.).

Als Übung wollte ich mir dann einen neuen Dienst für Windows erstellen, welcher genau dafür gedacht ist. Beim Recherchieren habe ich folgende Methoden gefunden, die ich für den Dienst benötige:
- OnStart( )
- OnPause( )
- OnContinue( )
- OnStop( )

Ist es überhaupt sinnvoll, das ganze über einen Windows Dienst zu implementieren? Meine Idee wäre nun, bei den Methoden OnStart und OnContinue einen separaten Thread zu starten, der diese Dauerschleife ausführt, und diesen in den Methoden OnPause und OnStop zu stoppen.

Da ich generell im Programmieren von Threads und Services noch überhaupt keine Erfahrung habe, wollte ich mich erkundigen, ob das eventuell der richtige Ansatz sein könnte oder ob es dafür einen "schöneren" oder sinnvolleren Weg gibt, da mir empfohlen wurde, Threads so gut wie möglich zu vermeiden face-smile .

Cheers,
Micha

Content-ID: 24188964237

Url: https://administrator.de/forum/windows-service-erstellen-24188964237.html

Ausgedruckt am: 22.12.2024 um 07:12 Uhr

Kraemer
Kraemer 12.10.2023 um 16:57:58 Uhr
Goto Top
Moin,

wenn du schon ein PS-Script hast, warum nutzt du das nicht einfach und realisierst das ganze über die Aufgabenplanung?

Gruß
michi.wtr
michi.wtr 12.10.2023 um 17:05:25 Uhr
Goto Top
Zitat von @Kraemer:

Moin,

wenn du schon ein PS-Script hast, warum nutzt du das nicht einfach und realisierst das ganze über die Aufgabenplanung?

Naja, würde theoretisch gehen, die geplante Aufgabe sollte dann aber theoretisch 24/7 ausgeführt werden, also eigentlich soll auf den Server der Pfad dauerhaft überwacht werden. Im Prinzip könnte ich ja auch das Skript einfach einmal starten, das wird dann auch dauerhaft ausgeführt, zur Not auch noch unter einer anderen Hintergrund Session, das würde ich dann nicht einmal mitbekommen.

Jedoch bin ich grade in der Ausbildung für Anwendungsentwicklung und dachte mir das wäre schön das ganze als eigenen Dienst zu implementieren. So würde die Überwachung stetig im Hintergrund laufen und könnte auch von Admins einfach gestoppt oder wieder gestartet werden.
7907292512
7907292512 12.10.2023 aktualisiert um 17:16:22 Uhr
Goto Top
Für sowas brauchst du kein Extra Dienst schreiben. Dafür reicht die Server-Rolle File Server Resource Manager (FSRM) die bereits in Windows integriert ist i.d.R. völlig aus. da kannst du Regeln für Dateien und Dateitypen erstellen und definieren was dann geschehen soll und natürlich auch eigene Skripte mit Parameterübergabe aufrufen.

Aber wenn das eh nur eine Übung sein soll, dann leg halt einfach mal los. Erfahrung sammeln ist immer gut ...

Gruß sid.
Doskias
Doskias 12.10.2023 um 17:17:56 Uhr
Goto Top
Zitat von @michi.wtr:
Zitat von @Kraemer:
wenn du schon ein PS-Script hast, warum nutzt du das nicht einfach und realisierst das ganze über die Aufgabenplanung?
Naja, würde theoretisch gehen, die geplante Aufgabe sollte dann aber theoretisch 24/7 ausgeführt werden, also eigentlich soll auf den Server der Pfad dauerhaft überwacht werden. Im Prinzip könnte ich ja auch das Skript einfach einmal starten, das wird dann auch dauerhaft ausgeführt, zur Not auch noch unter einer anderen Hintergrund Session, das würde ich dann nicht einmal mitbekommen.
Aber ein Skript in Dauerschleife ist unsicher. Aufgabenplanung kannst du recht einfach das Skript jede Minute ausführen und schauen ob die Datei in den letzten 60 Sekunden verändert wurde. Da brauchst du auch nach einem Serverneustart nicht drüber nachdenken, da die Aufgabe dann automatisch gestartet wird. Besser als ein Skript in Endlosschleife.

Jedoch bin ich grade in der Ausbildung für Anwendungsentwicklung und dachte mir das wäre schön das ganze als eigenen Dienst zu implementieren. So würde die Überwachung stetig im Hintergrund laufen und könnte auch von Admins einfach gestoppt oder wieder gestartet werden.
Admins können auch Aufgaben der Aufgabenplanung einfach starten und stoppen face-wink

Davon abgesehen: Jedes anständige Monitoring-Programm kann es entweder von Haus aus oder kann dein PS-Skript verarbeiten. Hat den Vorteil, dass du im Monitoring bereits eine vernünftige Auswertung und Aufschlüsselung fahren kannst. Beim Dienst nicht so wirklich.

Gruß
Doskias
Kraemer
Kraemer 12.10.2023 um 19:36:01 Uhr
Goto Top
Zitat von @Doskias:

Aber ein Skript in Dauerschleife ist unsicher.
ja ne - ist klar...
Wie kommt man nur auf solch einfältige Kommentare?
michi.wtr
michi.wtr 12.10.2023 aktualisiert um 20:06:49 Uhr
Goto Top
Zitat von @Doskias:

Aber ein Skript in Dauerschleife ist unsicher. Aufgabenplanung kannst du recht einfach das Skript jede Minute ausführen und schauen ob die Datei in den letzten 60 Sekunden verändert wurde. Da brauchst du auch nach einem Serverneustart nicht drüber nachdenken, da die Aufgabe dann automatisch gestartet wird.
Aber müsste ich hier nicht irgendwo die Informationen über die Dateien speichern? Das könnte sich ja theoretisch auch schon ziemlich aufblähen, wenn ich einen Ordner mit vielen Dateien habe was zudem das Skript verlangsamt. Der Dienst startet ja nur den System.IO.FileSystemWatcher der mir automatisch bei irgendwelchen Änderungen eine bestimmte Funktion ausführen kann.

Und noch ein größeres Problem:
Wenn sich jetzt ein Dateiname in den 60 Sekunden ändert, dann weiß ich ja nicht ob die Datei gelöscht und eine andere dafür erstellt wurde. Ich meine wenn die Namen zu 100% immer gleich bleiben, dann kann ich das wissen und nur die LastWriteTime anschauen.

Davon abgesehen: Jedes anständige Monitoring-Programm kann es entweder von Haus aus oder kann dein PS-Skript verarbeiten. Hat den Vorteil, dass du im Monitoring bereits eine vernünftige Auswertung und Aufschlüsselung fahren kannst. Beim Dienst nicht so wirklich.
Ist ja auch zu 100% korrekt, man sollte das Rad ja auch nicht neu erfinden. Dachte nur das wäre eine coole Idee zum Üben, da ich mir so einmal ein nützliches Tool habe und zum anderen mich mehr mit dem Programmieren, geschweige denn Windows Diensten mehr befassen kann. Ob das Ergebnis irgendwann zum Einsatz kommt bezweifle ich jedoch face-smile .

Gruß,
Micha
em-pie
em-pie 12.10.2023 um 21:52:46 Uhr
Goto Top
Moin,


Wenn sich jetzt ein Dateiname in den 60 Sekunden ändert, dann weiß ich ja nicht ob die Datei gelöscht und eine andere dafür erstellt wurde. Ich meine wenn die Namen zu 100% immer gleich bleiben, dann kann ich das wissen und nur die LastWriteTime anschauen.
Das kann man einfach prüfen:
  • im ersten Lauf: Hashwert der Datei speichern
  • Datei weg: Event auslösen
  • Datei-Hash anders: Event auslösen

Du musst die Hashwertwerte nur nachhaltig speichern. Wenn jemand den Task/ Dienst beendet, die Datei ersetzt und den Task/ Dienst wieder startet und der Hashwert nur zur Laufzeit des Skript im Speicher liegt, hast du verloren…
8585324113
8585324113 12.10.2023 um 23:55:28 Uhr
Goto Top
Ein richtiger Dienst ist sehr sinnvoll wegen der Vielzahl der Möglichkeiten und Werkzeugen.

Mit Visual Studio geht das gut.
michi.wtr
michi.wtr 13.10.2023 um 01:03:31 Uhr
Goto Top
Zitat von @8585324113:

Ein richtiger Dienst ist sehr sinnvoll wegen der Vielzahl der Möglichkeiten und Werkzeugen.

Mit Visual Studio geht das gut.

Ja hab es jetzt mal ausprobiert, funktioniert auch einwandfrei. Im Prinzip erstelle ich ein Logfile und setze dafür Dateiberechtigungen, wenn noch keins vorhanden ist. Wichtig ist eben, dass Benutzer nur Leserechte auf das Logfile haben, sonst kann der FileStream keine weiteren Infos reinschreiben. Danach überwache ich den Ordner und alle Änderungen werden schön in eine CSV geschrieben, die ich dann auch schön mit Excel oder PowerShell auslesen kann.

Nur leider ist es sehr Mühsam einen Dienst zu debuggen, da mir das zu aufwendig war, bzw. auch nicht ganz einfach laut den Microsoft Docs hab ich den Dienst einfach mal installiert und geprüft. Scheint (zumindest jetzt) alles toll zu laufen, nur Anfangs lies er sich leider nicht beenden, da ich den Thread nicht korrekt beendet hatte. Somit wollte der Dienst immer auf diesen warten, da der Timer zu groß war. Konnte den Dienst auch nicht mehr entfernen, erst nach Löschen aus der Registry und Neustart des PCs war er dann weg face-smile . Joa ich weiß, bestenfalls immer auf einer VM testen, aber leider kann ich bei mir keine installieren, da muss ich erstmal Hardware nachkaufen, traurig aber wahr.

Besten Dank euch allen,
Micha
canlot
canlot 13.10.2023 aktualisiert um 13:38:36 Uhr
Goto Top
Moin, das Problem hatte ich mit meiner Software.
Ich habe es so gelöst dass ich meinen ganzen Code entkoppelt habe und 2 Projekte zum Starten vom eigentlichen Code habe. Einer davon ist der Dienst und der andere ist eine Consolenapplikation.

Hiermit initialisiere ich und starte es im Dienst:
public partial class InstallationService : ServiceBase
    {
        Controller.ServiceController controller;
        public InstallationService()
        {
            InitializeComponent();
            controller = new Controller.ServiceController();
        }

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

        protected override void OnStop()
        {
            controller.Stop().Wait();
        }

        private void process1_Exited(object sender, EventArgs e)
        {

        }
    }
Und das ist die Consolenapplikation:
class Program
    {
        static void Main(string[] args)
        {
            ServiceController controller = new ServiceController();
            controller.Start(false);
            Console.Read();
            controller.Stop().Wait();
            Console.Read();
        }
    }

Hier kannst du es nachsehen: https://github.com/canlot/Installation-Agent/tree/v2

Du brauchst dafür dann aber 3 unterschiedliche Projekte in einer Solution.