Πώς μπορείτε να εκτελέσετε μια Python script ως υπηρεσία των Windows;

ψήφοι
211

Είμαι σκιαγραφώντας την αρχιτεκτονική για ένα σύνολο προγραμμάτων που μοιράζονται διάφορα αλληλένδετα αντικείμενα αποθηκεύονται σε μια βάση δεδομένων. Θέλω ένα από τα προγράμματα να ενεργεί ως υπηρεσία η οποία παρέχει ένα υψηλότερο διεπαφή επίπεδο για τις πράξεις σε αυτά τα αντικείμενα, και τα άλλα προγράμματα να έχουν πρόσβαση στα αντικείμενα μέσα από την εν λόγω υπηρεσία.

Είμαι σήμερα με στόχο για την Python και το πλαίσιο Django και οι τεχνολογίες για την υλοποίηση της εν λόγω υπηρεσίας με. Είμαι πολύ σίγουρος ότι μπορώ να καταλάβω πώς να daemonize το πρόγραμμα Python στο Linux. Ωστόσο, αυτό είναι ένα προαιρετικό στοιχείο spec ότι το σύστημα θα πρέπει να υποστηρίζει τα Windows. Έχω μικρή εμπειρία με τον προγραμματισμό των Windows και καθόλου εμπειρία σε όλες τις υπηρεσίες των Windows.

Είναι δυνατόν να τρέξει προγράμματα Python ως υπηρεσία των Windows (δηλαδή τρέχει αυτόματα χωρίς σύνδεση του χρήστη); Δεν θα πρέπει αναγκαστικά να εφαρμόσουν αυτό το μέρος, αλλά χρειάζομαι μια γενική ιδέα για το πώς θα πρέπει να γίνει προκειμένου να αποφασίσει αν θα σχεδιάσουμε προς αυτή την κατεύθυνση.

Επεξεργασία: Ευχαριστώ για όλες τις απαντήσεις μέχρι τώρα, είναι αρκετά περιεκτική. Θα ήθελα να μάθω κάτι ακόμα: Πώς είναι τα Windows επίγνωση της υπηρεσίας μου; Μπορώ να το διαχειριστεί με τα εγγενή βοηθητικά προγράμματα των Windows; Τι είναι το ισοδύναμο του βάζοντας ένα start / stop script στο /etc/init.d;

Δημοσιεύθηκε 28/08/2008 στις 15:28
πηγή χρήστη
Σε άλλες γλώσσες...                            


12 απαντήσεις

ψήφοι
220

Ναι μπορείς. Κάνω χρησιμοποιώντας τις βιβλιοθήκες pythoncom που έρχονται περιλαμβάνεται με ActivePython ή μπορεί να εγκατασταθεί με pywin32 (Python για τις επεκτάσεις των Windows).

Αυτό είναι ένα βασικό σκελετό για μια απλή υπηρεσία:

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)

Ο κωδικός σας θα πάει στη main()μέθοδο-συνήθως με κάποιο είδος άπειρο βρόχο που μπορεί να διακοπεί από τον έλεγχο μιας σημαίας, που έχετε ορίσει στην SvcStopμέθοδο

Απαντήθηκε 28/08/2008 στις 15:39
πηγή χρήστη

ψήφοι
23

Υπάρχουν δύο εναλλακτικές λύσεις για την εγκατάσταση ως υπηρεσία σχεδόν οποιοδήποτε εκτελέσιμο των Windows.

Μέθοδος 1: Χρήση instsrv και srvany από rktools.exe

Για τα Windows Home Server ή Windows Server 2003 (λειτουργεί με WinXP πάρα πολύ), τα Windows Server 2003 εργαλεία του Resource Kit έρχεται με βοηθητικά προγράμματα που μπορούν να χρησιμοποιηθούν σε συνδυασμό για το σκοπό αυτό, που ονομάζεται Instsrv.exe και srvany.exe . Δείτε αυτό το Microsoft KB άρθρο KB137890 για λεπτομέρειες σχετικά με το πώς να χρησιμοποιήσετε αυτά τα utils.

Για τα Windows Home Server, υπάρχει ένα μεγάλο φιλικό προς το χρήστη περιτύλιγμα για αυτές τις επιχειρήσεις κοινής ωφέλειας που ονομάζεται εύστοχα « Κάθε υπηρεσία εγκατάστασης ».

Μέθοδος 2: Χρήση ServiceInstaller για τα Windows NT

Υπάρχει και μια άλλη εναλλακτική χρήση ServiceInstaller για τα Windows NT ( download-θέση εδώ ) με τις οδηγίες python διαθέσιμα . Σε αντίθεση με το όνομα, λειτουργεί με τα Windows 2000 και Windows XP, καθώς και. Εδώ είναι μερικές οδηγίες για το πώς να εγκαταστήσετε ένα python script ως υπηρεσία.

Η εγκατάσταση ενός σεναρίου Python

Εκτελέστε ServiceInstaller να δημιουργήσει μια νέα υπηρεσία. (Σε αυτό το παράδειγμα, υποτίθεται ότι python έχει εγκατασταθεί στο C: \ python25)

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

Μετά την εγκατάσταση, ανοίξτε βοηθητική εφαρμογή Υπηρεσίες του Πίνακα Ελέγχου, επιλέξτε και ξεκινήστε την υπηρεσία PythonTest.

Μετά την αρχική μου απάντηση, παρατήρησα υπήρχαν στενά συνδεδεμένα Q & A ήδη αναρτηθεί στην ΑΑ. Δείτε επίσης:

Μπορώ να εκτελέσετε μια Python script ως υπηρεσία (στα Windows); Πως?

Πώς μπορώ να κάνω το Windows γνώση μιας υπηρεσίας που έχω γραμμένο σε Python;

Απαντήθηκε 28/02/2009 στις 09:30
πηγή χρήστη

ψήφοι
28

Αν και upvoted την επιλεγμένη απάντηση μια-δυο εβδομάδες πίσω, στο μεταξύ έχω παλέψει πολύ περισσότερο με αυτό το θέμα. Νιώθω σαν να έχεις μια ειδική εγκατάσταση Python και με τη χρήση ειδικών μονάδων εκτέλεσης ενός σεναρίου ως υπηρεσία είναι απλά λάθος τρόπο. Τι γίνεται με τη φορητότητα και τέτοια;

Σκόνταψα σε όλη την υπέροχη διευθυντή της υπηρεσίας για μη-πιπίλισμα , η οποία έκανε πολύ απλό και λογικό να ασχοληθεί με τις υπηρεσίες των Windows. Σκέφτηκα τότε που θα μπορούσε να περάσει επιλογές για να εγκατεστημένη υπηρεσία, θα μπορούσα κάλλιστα να επιλέξετε Python μου εκτελέσιμο και να περάσει το σενάριό μου ως επιλογή.

Δεν έχω ακόμα δοκιμάσει αυτή τη λύση, αλλά θα το κάνω τώρα και να ενημερώσετε τη θέση αυτή κατά μήκος της διαδικασίας. Είμαι επίσης ενδιαφέρονται για τη χρήση virtualenvs στα Windows, γι 'αυτό θα μπορούσε να καταλήξει σε ένα σεμινάριο αργά ή γρήγορα και σύνδεση με αυτό εδώ.

Απαντήθηκε 28/07/2014 στις 14:41
πηγή χρήστη

ψήφοι
11

Ο απλούστερος τρόπος για να επιτυγχάνουμε αυτό είναι να χρησιμοποιούν τη μητρική εντολή sc.exe:

sc create PythonApp binPath= "C:\Python34\Python.exe --C:\tmp\pythonscript.py"
  1. https://technet.microsoft.com/en-us/library/cc990289(v=ws.11).aspx
  2. τη δημιουργία μιας υπηρεσίας με sc.exe? πώς να περάσει στις παραμέτρους πλαίσιο
Απαντήθηκε 07/12/2016 στις 12:23
πηγή χρήστη

ψήφοι
-2

pysc: Διαχείριση ελέγχου υπηρεσιών σε Python

Παράδειγμα script για να τρέξει ως υπηρεσία λαμβάνεται από 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()

Δημιουργία και ξεκινήστε την υπηρεσία

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'))

Διακοπή και διαγραφή των υπηρεσιών

import pysc

service_name = 'test_xmlrpc_server'

pysc.stop(service_name)
pysc.delete(service_name)
pip install pysc
Απαντήθηκε 03/03/2017 στις 20:29
πηγή χρήστη

ψήφοι
7

Βήμα προς βήμα εξήγηση πώς να την κάνουμε να λειτουργήσει:

1- Πρώτη δημιουργήσει ένα αρχείο Python, ανάλογα με το βασικό σκελετό που αναφέρθηκε παραπάνω. Και να το αποθηκεύσετε σε μια διαδρομή, για παράδειγμα: «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 - Σε αυτό το βήμα θα πρέπει να εγγραφείτε υπηρεσία μας.

Εκτελέστε γραμμή εντολών ως διαχειριστής και πληκτρολογήστε ως εξής:

sc δημιουργήσει TestService binPath = "C: \ Python36 \ Python.exe c: \ PythonFiles \ AppServerSvc.py" εμφανιζόμενο = "TestService" start = auto

το πρώτο επιχείρημα της binPath είναι η πορεία της python.exe

Το δεύτερο επιχείρημα της binPath είναι η διαδρομή του αρχείου python σας που δημιουργήσαμε ήδη

Μην χάσετε ότι θα πρέπει να βάλετε ένα χώρο μετά από κάθε « = » σημάδι.

Στη συνέχεια, αν όλα είναι εντάξει, θα πρέπει να δείτε

[SC] CreateService ΕΠΙΤΥΧΙΑ

Τώρα υπηρεσία python σας έχει εγκατασταθεί ως υπηρεσία των Windows τώρα. Μπορείτε να το δείτε στη Διαχείριση Υπηρεσιών και μητρώου κάτω:

HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ TestService

3- Ok τώρα. Μπορείτε να ξεκινήσετε την υπηρεσία σας στο διευθυντή της υπηρεσίας.

Μπορείτε να εκτελέσετε κάθε αρχείο python που παρέχει αυτό το σκελετό υπηρεσίας.

Απαντήθηκε 29/06/2017 στις 08:37
πηγή χρήστη

ψήφοι
3

Ο απλούστερος τρόπος είναι να χρησιμοποιήσετε το: NSSM - το μη-πεολειξία Service Manager:

1 - κάνει download στην https://nssm.cc/download

2 - εγκαταστήστε το πρόγραμμα python ως υπηρεσία: Νίκη ζητήσει ως διαχειριστής

c:> nssm.exe εγκατάσταση WinService

3 - Στην κονσόλα NSSM's:

διαδρομή: C: \ Python27 \ Python27.exe

κατάλογο εκκίνησης: C: \ Python27

Επιχειρήματα: c: \ WinService.py

4 - ελέγξτε τις υπηρεσίες που δημιουργήθηκε για services.msc

Απαντήθηκε 27/09/2017 στις 14:05
πηγή χρήστη

ψήφοι
2

Άρχισα να φιλοξενεί ως υπηρεσία με pywin32 .

Όλα ήταν καλά, αλλά γνώρισα το πρόβλημα ότι η υπηρεσία δεν ήταν σε θέση να ξεκινήσει μέσα σε 30 δευτερόλεπτα (προεπιλεγμένο χρονικό όριο για Windows) κατά την εκκίνηση του συστήματος. Ήταν σημαντικό για μένα γιατί την εκκίνηση των Windows πραγματοποιήθηκε ταυτόχρονα σε πολλές εικονικές μηχανές που φιλοξενούνται σε ένα φυσικό μηχάνημα, και IO φορτίο ήταν τεράστιο. Μηνύματα σφάλματος ήταν:

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.

Πάλεψα πολύ με pywin, αλλά κατέληξε με τη χρήση NSSM όπως προτάθηκε σε αυτή την απάντηση . Ήταν πολύ εύκολο να μεταναστεύσουν σε αυτό.

Απαντήθηκε 12/10/2018 στις 13:07
πηγή χρήστη

ψήφοι
0

Η αποδεκτή απάντηση χρησιμοποιώντας win32serviceutilέργα, αλλά είναι περίπλοκη και καθιστά τον εντοπισμό σφαλμάτων και αλλάζει πιο δύσκολο. Είναι πολύ πιο εύκολο στη χρήση NSSM ( ο Διαχειριστής Μη πιπίλισμα Υπηρεσία) . Μπορείτε να γράψετε και άνετα διορθώσετε ένα κανονικό πρόγραμμα python και όταν λειτουργεί, τέλος, μπορείτε να χρησιμοποιήσετε NSSM να το εγκαταστήσετε ως υπηρεσία σε λιγότερο από ένα λεπτό:

Από αυξημένα (διαχειριστή) γραμμή εντολών τρέχετε nssm.exe install NameOfYourServiceκαι θα συμπληρώσετε σε αυτές τις επιλογές:

  • διαδρομή : (η διαδρομή προς python.exe π.χ. C:\Python27\Python.exe)
  • Επιχειρήματα : (η διαδρομή προς το σενάριο python σας, π.χ. c:\path\to\program.py)

Με την ευκαιρία, αν εκτυπώσεις πρόγραμμά σας χρήσιμα μηνύματα που θέλετε να κρατήσετε σε ένα αρχείο καταγραφής NSSM μπορεί επίσης να χειριστεί αυτό και πολύ περισσότερο για σας.

Απαντήθηκε 10/11/2018 στις 15:52
πηγή χρήστη

ψήφοι
0

Για όποιον θέλει να δημιουργήσει την υπηρεσία σε VENV ή Pycharm !!!!!!!

Μετά την ανάγνωση όλων των anwsers και να δημιουργήσει κάποια σενάρια, αν μπορείτε να εκτελέσετε python service.py installκαι python service.py debug, αλλά python service.py startδεν έχει καμία απάντηση.

Ίσως αυτό είναι που προκαλείται από venv πρόβλημα, γιατί παράθυρα υπηρεσία ξεκινήσετε την υπηρεσία σας από exec PROJECT\venv\Lib\site-packages\win32\pythonservice.exe.

Μπορείτε να χρησιμοποιήσετε powershellή cmdνα δοκιμάσετε την υπηρεσία σας για να βρείτε λεπτομέρειες πιο λάθος του.

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)

Αν έχετε κάποιο λάθος, όπως εγώ, τότε μπορείτε να ελέγξετε την απάντησή μου σε άλλη ερώτηση, το σταθερό και μετά τον κωδικό μου εδώ .

Απαντήθηκε 29/05/2019 στις 08:57
πηγή χρήστη

ψήφοι
0

nssm για το python 3+

(Ι μετατρέπεται αρχείο .py μου να .exe με pyinstaller)

nssm: όπως είπε πριν

  • τρέξει nssm εγκατάσταση {όνομα_υπηρεσίας}
  • Στην κονσόλα NSSM's:

    διαδρομής: μονοπάτι \ να \ \ Program.exe σας

    Κατάλογο εκκίνησης: διαδρομή \ να \ \ #same σας, καθώς το μονοπάτι, αλλά χωρίς Program.exe σας

    Επιχειρήματα: άδειο

Απαντήθηκε 05/06/2019 στις 00:42
πηγή χρήστη

ψήφοι
0

Ένα πλήρες παράδειγμα pywin32 χρησιμοποιώντας βρόχο ή δευτερεύουσα συζήτηση

Αφού εργάστηκε σε αυτό και εκτός για λίγες μέρες, εδώ είναι η απάντηση που θα επιθυμούσαν να βρουν, χρησιμοποιώντας pywin32 να το κρατήσει ωραίο και αυτοδύναμες.

Αυτό είναι πλήρη κώδικα εργασίας για ένα βρόχο που βασίζεται και ένα διάλυμα βασισμένη σε νήματα. Μπορεί να λειτουργήσει τόσο python 2 και 3, αν και έχω δοκιμαστεί μόνο την τελευταία έκδοση για 2.7 και Win7. Ο βρόχος πρέπει να είναι καλό για τον κωδικό δημοσκοπήσεις, και το πέλμα πρέπει να συνεργαστεί με περισσότερους διακομιστή όπως κώδικα. Φαίνεται να λειτουργεί καλά με τη σερβιτόρα του διακομιστή WSGI που δεν έχει ένα πρότυπο τρόπο για να κλείσει ομαλά.

Θα ήθελα επίσης να σημειωθεί ότι φαίνεται να υπάρχει ένα σωρό παραδείγματα εκεί έξω, όπως αυτό που είναι σχεδόν χρήσιμα, αλλά στην πραγματικότητα παραπλανητική, επειδή έχουν κοπεί και να επικολληθεί άλλα παραδείγματα στα τυφλά. Μπορεί να κάνω λάθος. αλλά γιατί να δημιουργήσετε ένα συμβάν αν δεν μπορείτε να περιμένετε;

Τούτου λεχθέντος εξακολουθώ να νιώθω ότι είμαι σε κάπως τρεμάμενο έδαφος εδώ, ιδιαίτερα σε σχέση με το πόσο καθαρά η έξοδος από την έκδοση νήμα είναι, αλλά τουλάχιστον πιστεύω ότι υπάρχει τίποτα παραπλανητικό εδώ.

Για να εκτελέσετε απλά αντιγράψτε τον κώδικα σε ένα αρχείο και ακολουθήστε τις οδηγίες.

# uncomment mainthread() or mainloop() call below
# run without parameters to see HandleCommandLine options
# install service with "install" and remove with "remove"
# run with "debug" to see print statements
# run with "start" and "stop" and watch for files to appear
# check Windows EventViever for log messages

import socket
import threading
import time
from random import randint
from os import path

import servicemanager
import win32event
import win32service
import win32serviceutil
# see http://timgolden.me.uk/pywin32-docs/contents.html for details


def dummytask_once(msg='once'):
    fn = path.join(path.dirname(__file__),
                '%s_%s.txt' % (msg, randint(1, 10000)))
    with open(fn, 'w') as fh:
        print(fn)
        fh.write('')


def dummytask_loop():
    while True:
        dummytask_once(msg='loop')
        time.sleep(3)


class MyThread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        dummytask_loop()


class SMWinservice(win32serviceutil.ServiceFramework):
    _svc_name_ = 'PyWinSvc'
    _svc_display_name_ = 'Python Windows Service'
    _svc_description_ = 'An example of a windows service in Python'

    @classmethod
    def parse_command_line(cls):
        win32serviceutil.HandleCommandLine(cls)

    def __init__(self, args):
        win32serviceutil.ServiceFramework.__init__(self, args)
        self.stopEvt = win32event.CreateEvent(None, 0, 0, None)  # create generic event
        socket.setdefaulttimeout(60)

    def SvcStop(self):
        servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                            servicemanager.PYS_SERVICE_STOPPED,
                            (self._svc_name_, ''))
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.stopEvt)  # raise event

    def SvcDoRun(self):
        servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                            servicemanager.PYS_SERVICE_STARTED,
                            (self._svc_name_, ''))
        # UNCOMMENT ONE OF THESE
        # self.mainthread()
        # self.mainloop()

    # Wait for stopEvt indefinitely after starting thread.
    def mainthread(self):
        print('thread start')
        self.server = MyThread()
        self.server.start()
        win32event.WaitForSingleObject(self.stopEvt, win32event.INFINITE)
        print('thread done')

    # Wait for stopEvt event in loop.
    def mainloop(self):
        print('loop start')
        rc = None
        while rc != win32event.WAIT_OBJECT_0:
            dummytask_once()
            rc = win32event.WaitForSingleObject(self.stopEvt, 3000)
        print('loop done')


if __name__ == '__main__':
    SMWinservice.parse_command_line()
Απαντήθηκε 27/01/2020 στις 00:52
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more