![]() |
Wie Remote Update eine Windows-Service?
Gegeben ist ein lokales Netzwerk. Wie kann man am elegantesten einen auf dem Server laufenden Windows Service von einem Client aus aktualisieren?
Momentan überlege folgenden Ablauf: - Neue Exe an den Windows Service übertragen - Den Service veranlassen eine Windows Aufgabe zu starten, welche den Service stoppt, eine andere Exe aufruft, die das Update installiert und den Service wieder startet. Gibt es elegantere Lösungen? Kann ein Service überhaupt eine Aufgabe starten? Vielen Dank für Anregungen. |
AW: Wie Remote Update eine Windows-Service?
Oder einen 2. Updatedienst einrichten, welcher diese Aufgabe übernimmt.
|
AW: Wie Remote Update eine Windows-Service?
Also wir haben das bei uns ganz pragmatisch gelöst... es wurde eine Freigabe eingerichtet, so dass man aus dem Netz auf den Installationsordner des Services zugreifen und die Exe austauschen kann... außerdem läuft auf dem Server ein vnc Server, um sich mit dem Server verbinden und den Dienst vor dem Austausch stoppen zu können.
Gruß Uli |
AW: Wie Remote Update eine Windows-Service?
Schau Dir bitte mal den Kommandozeilenbefehl sc an.
Damit kann man u. a. Services starten und stoppen, auch auf "fremden" Rechnern. Dein Problem müsste sich somit per Batchdatei lösen lassen. Ungetestet und nur vermutet in etwa sowas:
Code:
Literatur dazu:
sc \\Server stop "service name"
copy Service.exe \\Server\Pfad\Service.exe sc \\Server start "service name" ![]() ![]() |
AW: Wie Remote Update eine Windows-Service?
Zitat:
SC wäre eine Alternative, muss ich mal schauen, ob das Remote klappt. Müssen dazu auf dem Server irgend welche Rechte gesetzt werden, das man sowas darf? |
AW: Wie Remote Update eine Windows-Service?
Der Benutzer muss Adminrechte auf dem remoten Server besitzen
|
AW: Wie Remote Update eine Windows-Service?
Ich gehe mal davon aus, dass der Nutzer, der SC ausführt, das Recht haben muss, auf dem Server Dienste zu starten und zu beenden und Schreibrechte für das Verzeichnis benötigt, in dem die Service.exe liegt.
|
AW: Wie Remote Update eine Windows-Service?
Hmm, ich glaub, das ist auch schon wieder nix. Ich glaub nicht, dass das Admin-Passwort immer verfügbar ist. Bleibt wohl nur ein Update-Dienst.
Oder kann ein Dienst ein Windows Task anwerfen? |
AW: Wie Remote Update eine Windows-Service?
Liste der Anhänge anzeigen (Anzahl: 1)
Der Ansatz mit einem zweiten Dienst zu arbeiten habe ich auch schon verfolgt.
UpdateService mit einem Timer versehen. Der Timer prüft regelmässig ob eine aktuellere Version des Arbeitsdienstes rumliegt und führt wenn nötig eine Aktualisierung durch:
Delphi-Quellcode:
Im Anhang die ServiceManager.pas welche mal irgendwo gefunden habe.
// === Timer - UpdateCheck =====================================================
procedure TnwUpdateService.OnUpdateCheckTimer(Sender: TObject); var ServiceManager: TServiceManager; oldName, NewName, UpdFile : String; tts : Integer; begin newname := GetScriptDir +'\n_Server.old'; oldname := GetScriptDir +'\n_Server.exe'; updfile := GetScriptDir +'\n_DataServer\n_Server.exe'; // WriteLog('Updatechecker','Check on every 30s'); // = Check for local update if Fileexists(updfile) then begin WriteLog('Updatechecker','Found Update for "n_DataServer.exe"'); ServiceManager := TServiceManager.Create; ServiceManager.Connect; ServiceManager.OpenServiceConnection('nwDataServer'); with ServiceManager do begin // Stoping Service if it is running if ServiceRunning then begin WriteLog('Updatechecker','Trying to stop "n_DataServer.exe"'); StopService; end else WriteLog('Updatechecker','Is not running: "n_DataServer.exe"'); // = Check repeatetly tts := 0; repeat tts := tts +1; sleep(1000) until (tts > 30) OR (Servicemanager.ServiceStopped); If Servicemanager.ServiceStopped then WriteLog('Updatechecker','was or is stopped: "n_DataServer.exe"') else begin WriteLog('Updatechecker','[ERROR] Could not stop "n_DataServer.exe"'); exit; end; // = Replace current server.exe with the new one WriteLog('Updatechecker','Current Version was: ' +fGetFileVersion(oldname)); WriteLog('Updatechecker','New Version is : ' +fGetFileVersion(updfile)); // = Rename current server.exe to server.old if Fileexists(newname) then DeleteFile(newname); sleep(100); newName := ChangeFileExt(oldName, '.old'); sleep(100); RenameFile(oldName, newName); sleep(100); // = Move update.exe to currentdir MoveFile(PChar(updfile),PChar(oldname)); sleep(100); // = Start Service if ServiceStopped then begin WriteLog('Updatechecker','Trying to start "n_DataServer.exe"'); StartService; end; sleep(100); // = Check repeatetly tts := 0; repeat tts := tts +1; sleep(1000) until (tts > 30) OR (Servicemanager.ServiceRunning); If Servicemanager.ServiceRunning then WriteLog('Updatechecker','Is running: "n_DataServer.exe"') else begin WriteLog('Updatechecker','[ERROR] Could not start "n_DataServer.exe"'); exit; end; end; // = Free the instance FreeAndNil(ServiceManager); end; end; :duck: Bitte nicht mit Prügel aufwarten, mein Code hat sicher Optimierungspotential... |
AW: Wie Remote Update eine Windows-Service?
Wobei dieses Vorgehen doch grundsätzlich ein hohes Sicherheitsrisiko birgt.
|
AW: Wie Remote Update eine Windows-Service?
Warum den Admin nehmen?
Ich würd' auf dem Server einen Benutzer anlegen (lassen), der genau die Aufgabe hat, den Dienst zu starten und zu stoppen und Lese- und Schreibrechte im Verzeichnis der Service.exe hat. Mit diesem User wird dann der Austausch des Services vorgenommen. Dafür braucht man nicht den Admin zu bemühen. Alternative: Wenn im Service die Version seiner selbst bekannt ist, so könnte der Service doch zu einem definierten Zeitpunkt (täglich 3:00 Uhr oder sowas) an einer definierten Stelle nachschauen, ob es eine neue Version seiner Selbst gibt ('ne Textdatei oder sowas). Steht dort, dass es eine neue Version gibt, so startet er selbst per ShellExecute die oben vorgeschlagene Batchdatei. Die beendet ihn dann, kopiert die neue Service.exe und starte den Dienst dann. andere Alternative: Der Service prüft, ob an einer bestimmten Stelle eine Datei liegt, die den gleichen Dateinamen hat, wie erst selbst, dann wird die Batchdatei gestartet, zusätzlich löscht die Batchdatei nach dem Kopieren noch die "Quelldatei". Das könnte dann etwa so aussehen:
Code:
\\Quellrechner\Pfad\Service.exe könnte natürlich auch 'ne für den Service verfügbare Freigabe sein.
sc stop "service name"
copy \\Quellrechner\Pfad\Service.exe Service.exe del \\Quellrechner\Pfad\Service.exe sc start "service name" Oder wenn es auf dem Server schon 'ne Freigabe gibt, dann wird die neue Service.exe dort abgelegt. |
AW: Wie Remote Update eine Windows-Service?
@nahpets ein Service darf Prozesse starten?
|
AW: Wie Remote Update eine Windows-Service?
Prinzipell spricht da erstmal nix gegen, ist doch eigentlich auch nur 'ne normale Anwendung.
Der Nutzer, mit dem der Service sich anmeldet, muss halt die entsprechenden Rechte haben. |
AW: Wie Remote Update eine Windows-Service?
Mir fiel da gerade noch eine Alternative ein, die ohne Programmierung laufen müsste:
Man nutze den Taskplaner des Servers und stelle sicher, dass es "irgendwo im Netz" ein Verzeichnis gibt, auf das sowohl der Nutzer, mit dem der Taskplaner arbeitet, als auch derjenige, der die neue Service.exe zur Verfügung stellt, Schreib- und Leserechte haben. Dann könnte das Ganze mit 'ner Batchdatei funktionieren:
Code:
Wenn Du jetzt noch das Kommandozeilentool Blat zur Verfügung hast, kannst Du Dir die Log-Datei per Mail zuschicken lassen und weißt damit, ob der Service ausgetauscht wurde und kannst der Mail Infos über Erfolg oder Misserfolg entnehmen.
@echo off
set Quelldatei="\\Quellrechner\Pfad\Service.exe" set Zieldatei="Laufwerk:\Verzeichnis\Service.exe" set ServiceName="service name" set log=%~dpn0.log if exist %Quelldatei% ( echo Service %ServiceName% wird ausgetauscht. >>%log% sc stop %ServiceName% >%log% copy %Quelldatei% %Zieldatei% >>%log% del %Quelldatei% >>%log% sc start %ServiceName% >>%log% sc query %ServiceName% >>%log% ) Blat gibt es hier: ![]() oder hier: ![]() |
AW: Wie Remote Update eine Windows-Service?
Mal eine blöde Frage: Warum dieser Aufwand? In der Zeit, wo man sowas ausprogrammiert, gebatcht oder ähnliches hat, hat man das zig mal von Hand ersetzt. Oder soll der Service regelmäßig oder bei vielen Installationen aktualisiert werden?
Man kann für sowas auch eine Installationsroutine schreiben. |
AW: Wie Remote Update eine Windows-Service?
Zitat:
@nahpets Die Idee ist gut, ich werd mir wohl jetzt mal Gedanken machen, wofür ich mich entscheide. Danke |
AW: Wie Remote Update eine Windows-Service?
Zitat:
Code:
Übrigens sollte man mit Anführungszeichen innerhalb von Umgebungsvariablen vorsichtig sein. Wenn man sie beim Verwenden der Variable mal nicht haben will, bekommt man sie nicht mehr weg. Sowas kommt zum Beispiel vor, wenn man einen komplexen String aus mehreren Variablen zusammenbauen will. Das führt bei Quotes im Variablenwert u.U. zur Dopplung selbiger mit entsprechend "tollen" Effekten. Daher ist es besser, die Anführungszeichen erst bei der Verwendung von Variablen zu setzen. Bei dem Beispiel hier hab ich mir diese Änderung trotzdem gespart (bis auf das "%log%" am Ende).
@echo off
set Quelldatei="\\Quellrechner\Pfad\Service.exe" set Zieldatei="Laufwerk:\Verzeichnis\Service.exe" set ServiceName="service name" set log=%~dpn0.log if exist %Quelldatei% ( echo -- echo %date% %time% echo Service %ServiceName% wird ausgetauscht. sc stop %ServiceName% copy %Quelldatei% %Zieldatei% del %Quelldatei% sc start %ServiceName% sc query %ServiceName% )>>"%log%" Für den Fall, dass die einfache Umlenkung beim Stoppen des Dienstes Absicht war, kann man die doppelte Umlenkung in meiner Variante auch in eine einfache ändern oder das Log zu Beginn des Skripts löschen. MfG Dalai |
AW: Wie Remote Update eine Windows-Service?
@Dalai
Mit dem > hast Du recht, es hätte eine Zeile höher gemusst, so, wie ich es schrieb, bekommt man ja die erste Meldung nie zu Gesicht, da die zweite Ausgabe die Datei neu erstellt. Prinzipiell war es schon so gemeint, dass die Log-Datei jedes Mal neu erstellt wird, um sie bei Bedarf per Blat verschicken zu können und damit nicht irgendwann eine annähernd endlose Datei zu verschicken. War halt einfach so hingedaddelt, dass man die Umleitung der Ausgabe auch hinter der schließenden Klammer machen kann, wusste ich nicht. Das ist natürlich viel eleganter. Deine Anmerkung zu den " ist auch korrekt, da kann man ggfls. schon "ungewöhnliche" Nebeneffekte erleben, wenn die " mal nicht passend sind, vor allem die, die irgendwo in Variabeln versteckt sind. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:30 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz