Frage

Ich skizziere die Architektur für eine Reihe von Programmen, die verschiedene miteinander verbundene, in einer Datenbank gespeicherte Objekte gemeinsam nutzen.Ich möchte, dass eines der Programme als Dienst fungiert, der eine übergeordnete Schnittstelle für Operationen an diesen Objekten bereitstellt, und dass die anderen Programme über diesen Dienst auf die Objekte zugreifen.

Ich strebe derzeit Python und das Django-Framework als Technologien zur Implementierung dieses Dienstes an.Ich bin mir ziemlich sicher, dass ich herausgefunden habe, wie ich das Python-Programm unter Linux dämonisieren kann.Allerdings ist es eine optionale Spezifikation, dass das System Windows unterstützen sollte.Ich habe wenig Erfahrung mit der Windows-Programmierung und überhaupt keine Erfahrung mit Windows-Diensten.

Ist es möglich, Python-Programme als Windows-Dienst auszuführen (z.e.automatisch ohne Benutzeranmeldung ausführen)? Ich muss diesen Teil nicht unbedingt umsetzen, aber ich brauche eine grobe Vorstellung davon, wie es gemacht werden würde, um zu entscheiden, ob ich in diese Richtung entwerfen möchte.

Bearbeiten:Vielen Dank für alle bisherigen Antworten, sie sind recht umfassend.Ich würde gerne noch etwas wissen: Wie erkennt Windows meinen Dienst?Kann ich es mit den nativen Windows-Dienstprogrammen verwalten? Was entspricht dem Einfügen eines Start-/Stopp-Skripts in /etc/init.d?

War es hilfreich?

Lösung

Ja, du kannst.Ich mache es mit den mitgelieferten Pythoncom-Bibliotheken ActivePython oder kann mit installiert werden pywin32 (Python für Windows-Erweiterungen).

Dies ist ein Grundgerüst für einen einfachen Dienst:

import win32serviceutil
import win32service
import win32event
import servicemanager
import socket


class AppServerSvc (win32serviceutil.ServiceFramework):
    _svc_name_ = "TestService"
    _svc_display_name_ = "Test Service"

    def __init__(self,args):
        win32serviceutil.ServiceFramework.__init__(self,args)
        self.hWaitStop = win32event.CreateEvent(None,0,0,None)
        socket.setdefaulttimeout(60)

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)

    def SvcDoRun(self):
        servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                              servicemanager.PYS_SERVICE_STARTED,
                              (self._svc_name_,''))
        self.main()

    def main(self):
        pass

if __name__ == '__main__':
    win32serviceutil.HandleCommandLine(AppServerSvc)

Ihr Code würde in die gehen main() Methode – normalerweise mit einer Art Endlosschleife, die durch die Überprüfung eines Flags unterbrochen werden kann, das Sie in der gesetzt haben SvcStop Methode

Andere Tipps

Obwohl ich die gewählte Antwort vor ein paar Wochen positiv bewertet habe, hatte ich in der Zwischenzeit viel mehr Probleme mit diesem Thema.Es scheint, als wäre eine spezielle Python-Installation und die Verwendung spezieller Module zum Ausführen eines Skripts als Dienst einfach der falsche Weg.Was ist mit der Portabilität und dergleichen?

Ich bin über das Wunderbare gestolpert Nicht saugender Servicemanager, was den Umgang mit Windows-Diensten wirklich einfach und sinnvoll machte.Ich dachte, da ich Optionen an einen installierten Dienst übergeben könnte, könnte ich genauso gut meine ausführbare Python-Datei auswählen und mein Skript als Option übergeben.

Ich habe diese Lösung noch nicht ausprobiert, aber ich werde es jetzt tun und diesen Beitrag im Laufe des Prozesses aktualisieren.Ich interessiere mich auch für die Verwendung von Virtualenvs unter Windows, daher werde ich vielleicht früher oder später ein Tutorial erstellen und hier darauf verlinken.

Es gibt einige Alternativen für die Installation praktisch aller ausführbaren Windows-Dateien als Dienst.

Methode 1:Verwenden Sie instsrv und srvany von rktools.exe

Für Windows Home Server oder Windows Server 2003 (funktioniert auch mit WinXP) ist die Windows Server 2003 Resource Kit-Tools wird mit Dienstprogrammen geliefert, die hierfür parallel verwendet werden können instsrv.exe Und srvany.exe.Siehe diesen Microsoft KB-Artikel KB137890 Einzelheiten zur Verwendung dieser Dienstprogramme finden Sie hier.

Für Windows Home Server gibt es einen großartigen, benutzerfreundlichen Wrapper für diese Dienstprogramme mit dem treffenden Namen „Jeder Service-Installer".

Methode 2:Verwenden Sie ServiceInstaller für Windows NT

Es gibt eine weitere Alternative mit ServiceInstaller für Windows NT (hier herunterladbar) mit Python-Anweisungen verfügbar.Entgegen dem Namen funktioniert es sowohl mit Windows 2000 als auch mit Windows XP.Hier finden Sie einige Anweisungen zum Installieren eines Python-Skripts als Dienst.

Installieren eines Python-Skripts

Führen Sie ServiceInstaller aus, um einen neuen Service zu erstellen.(In diesem Beispiel wird angenommen, dass Python unter c: python25 installiert ist)

Service Name  : PythonTest
Display Name : PythonTest 
Startup : Manual (or whatever you like)
Dependencies : (Leave blank or fill to fit your needs)
Executable : c:\python25\python.exe
Arguments : c:\path_to_your_python_script\test.py
Working Directory : c:\path_to_your_python_script

Öffnen Sie nach der Installation das Dienste -Applet des Bedienfelds, wählen Sie den Pythontest -Service aus und starten Sie den Dienst.

Nach meiner ersten Antwort fiel mir auf, dass auf SO bereits eng verwandte Fragen und Antworten gepostet wurden.Siehe auch:

Kann ich ein Python-Skript als Dienst ausführen (unter Windows)?Wie?

Wie mache ich Windows auf einen Dienst aufmerksam, den ich in Python geschrieben habe?

Der einfachste Weg, dies zu erreichen, ist die Verwendung des nativen Befehls sc.exe:

sc create PythonApp binPath= "C:\Python34\Python.exe --C:\tmp\pythonscript.py"

Verweise:

  1. https://technet.microsoft.com/en-us/library/cc990289(v=ws.11).aspx
  2. Wie übergebe ich beim Erstellen eines Dienstes mit sc.exe Kontextparameter?

Der einfachste Weg ist die Verwendung von: NSSM – der Non-Sucking Service Manager:

1 - Download aktivieren https://nssm.cc/download

2 – Installieren Sie das Python-Programm als Dienst:Gewinnen Sie Eingabeaufforderung als Administrator

c:>nssm.exe installiert WinService

3 – Auf der NSSM-Konsole:

Weg:C:\Python27\Python27.exe

Startverzeichnis:C:\Python27

Argumente:c:\WinService.py

4 – Überprüfen Sie die erstellten Dienste auf services.msc

Schritt-für-Schritt-Erklärung, wie es funktioniert:

1- Erstellen Sie zunächst eine Python-Datei gemäß dem oben genannten Grundgerüst.Und speichern Sie es zum Beispiel in einem Pfad:„c:\PythonFiles\AppServerSvc.py“

import win32serviceutil
import win32service
import win32event
import servicemanager
import socket


class AppServerSvc (win32serviceutil.ServiceFramework):
    _svc_name_ = "TestService"
    _svc_display_name_ = "Test Service"


    def __init__(self,args):
        win32serviceutil.ServiceFramework.__init__(self,args)
        self.hWaitStop = win32event.CreateEvent(None,0,0,None)
        socket.setdefaulttimeout(60)

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)

    def SvcDoRun(self):
        servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                          servicemanager.PYS_SERVICE_STARTED,
                          (self._svc_name_,''))
        self.main()

    def main(self):
        # Your business logic or call to any class should be here
        # this time it creates a text.txt and writes Test Service in a daily manner 
        f = open('C:\\test.txt', 'a')
        rc = None
        while rc != win32event.WAIT_OBJECT_0:
            f.write('Test Service  \n')
            f.flush()
            # block for 24*60*60 seconds and wait for a stop event
            # it is used for a one-day loop
            rc = win32event.WaitForSingleObject(self.hWaitStop, 24 * 60 * 60 * 1000)
        f.write('shut down \n')
        f.close()

if __name__ == '__main__':
    win32serviceutil.HandleCommandLine(AppServerSvc)

2 – In diesem Schritt sollten wir unseren Dienst registrieren.

Führen Sie die Eingabeaufforderung aus als Administrator und geben Sie Folgendes ein:

sc create TestService binpath= „C:\Python36\Python.exe c:\PythonFiles\AppServerSvc.py“ DisplayName= „TestService“ start= auto

das erste Argument von binpath ist der Pfad von python.exe

zweites Argument von binpath Ist der Pfad Ihrer Python-Datei das wir bereits erstellt haben

Vergessen Sie nicht, nach jedem „“ ein Leerzeichen einzufügen.=" Zeichen.

Wenn dann alles in Ordnung ist, sollten Sie nachsehen

[SC] CreateService ERFOLGREICH

Jetzt ist Ihr Python-Dienst als Windows-Dienst installiert.Sie können es im Service Manager und in der Registrierung sehen unter:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services estService

3- Ok, jetzt.Sie können Ihren Dienst im Service Manager starten.

Sie können jede Python-Datei ausführen, die dieses Dienstgerüst bereitstellt.

Ich habe mit Hosting als Dienstleistung begonnen pywin32.

Alles war in Ordnung, aber ich hatte das Problem, dass der Dienst beim Systemstart nicht innerhalb von 30 Sekunden (Standardzeitlimit für Windows) gestartet werden konnte.Dies war für mich von entscheidender Bedeutung, da der Windows-Start gleichzeitig auf mehreren virtuellen Maschinen stattfand, die auf einer physischen Maschine gehostet wurden, und die E/A-Last enorm war.Fehlermeldungen waren:

Error 1053: The service did not respond to the start or control request in a timely fashion.

Error 7009: Timeout (30000 milliseconds) waiting for the <ServiceName> service to connect.

Ich habe viel mit Pywin gekämpft, aber am Ende habe ich NSSM so verwendet, wie es vorgeschlagen wurde in dieser Antwort.Die Migration dorthin war sehr einfach.

Die akzeptierte Antwort mit win32serviceutil funktioniert, ist aber kompliziert und erschwert das Debuggen und Ändern.Es ist weit einfacher zu verwendendes NSSM (der Non-Sucking Service Manager).Sie schreiben und debuggen bequem ein normales Python-Programm und wenn es endlich funktioniert, installieren Sie es mit NSSM in weniger als einer Minute als Dienst:

Führen Sie die Eingabeaufforderung über eine Eingabeaufforderung mit erhöhten Rechten (Administrator) aus nssm.exe install NameOfYourService und Sie füllen diese Optionen aus:

  • Weg:(Der Pfad zu python.exe z.B. C:\Python27\Python.exe)
  • Argumente:(Der Pfad zu Ihrem Python-Skript, z. B. c:\path\to\program.py)

Übrigens: Wenn Ihr Programm nützliche Meldungen ausgibt, die Sie in einer Protokolldatei aufbewahren möchten, kann NSSM dies und noch viel mehr für Sie erledigen.

Für alle, die Dienste in VENV oder Pycharm erstellen möchten !!!!!!!

Nachdem Sie alle Antworten gelesen und einige Skripte erstellt haben, können Sie diese ausführen python service.py install Und python service.py debug, Aber python service.py start hat keine Antwort.

Möglicherweise liegt es an einem Venv-Problem, weil der Windows-Dienst Ihren Dienst durch Exec startet PROJECT\venv\Lib\site-packages\win32\pythonservice.exe.

Sie können verwenden powershell oder cmd um Ihren Dienst zu testen und weitere Fehlerdetails zu finden.

PS C:\Users\oraant> E:

PS E:\> cd \Software\PythonService\venv\Lib\site-packages\win32

PS E:\Software\PythonService\venv\Lib\site-packages\win32> .\pythonservice.exe -debug ttttt
Debugging service ttttt - press Ctrl+C to stop.
Error 0xC0000004 - Python could not import the service's module

Traceback (most recent call last):
  File "E:\Software\PythonService\my_service.py", line 2, in <module>
    import win32serviceutil
ModuleNotFoundError: No module named 'win32serviceutil'

(null): (null)

Wenn Sie wie ich einen Fehler erhalten, können Sie meine Antwort in einer anderen Frage überprüfen. Ich habe ihn behoben und meinen Code gepostet Hier.

nssm in Python 3+ aktiviert

(Ich habe meine .py-Datei mit pyinstaller in .exe konvertiert)

nssm:wie schon gesagt

  • Führen Sie nssm install {ServiceName} aus
  • Auf der NSSM-Konsole:

    Weg: Pfad\zu\Ihrem\Programm.exe

    Startverzeichnis: path o\your\ #identisch mit dem Pfad, jedoch ohne Ihre program.exe

    Argumente:leer

pysc: Service Control Manager auf Python

Beispielskript zur Ausführung als Dienst entnommen aus pythonhosted.org:

from xmlrpc.server import SimpleXMLRPCServer

from pysc import event_stop


class TestServer:

    def echo(self, msg):
        return msg


if __name__ == '__main__':
    server = SimpleXMLRPCServer(('127.0.0.1', 9001))

    @event_stop
    def stop():
        server.server_close()

    server.register_instance(TestServer())
    server.serve_forever()

Dienst erstellen und starten

import os
import sys
from xmlrpc.client import ServerProxy

import pysc


if __name__ == '__main__':
    service_name = 'test_xmlrpc_server'
    script_path = os.path.join(
        os.path.dirname(__file__), 'xmlrpc_server.py'
    )
    pysc.create(
        service_name=service_name,
        cmd=[sys.executable, script_path]
    )
    pysc.start(service_name)

    client = ServerProxy('http://127.0.0.1:9001')
    print(client.echo('test scm'))

Dienst stoppen und löschen

import pysc

service_name = 'test_xmlrpc_server'

pysc.stop(service_name)
pysc.delete(service_name)
pip install pysc
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top