Domanda

Io sono schizzi di architettura per un insieme di programmi che condividere i vari oggetti correlati tra loro memorizzati in un database.Voglio uno dei programmi di agire come un servizio che fornisce un più alto livello di interfaccia per le operazioni di questi oggetti, e altri programmi per accedere a oggetti tramite questo servizio.

Attualmente sto puntando per Python e Django quadro tecnologie per implementare il servizio con.Io sono abbastanza sicuro che figura come eseguito come demone del programma Python in ambiente Linux.Tuttavia, è un optional spec voce che il sistema di supporto di Windows.Ho poca esperienza con la programmazione di Windows e nessuna esperienza con i servizi di Windows.

È possibile eseguire una di programmi Python come un servizio di Windows (io.e.eseguire automaticamente senza che l'utente login)? Non necessariamente implementare questa parte, ma ho bisogno di un idea di come potrebbe essere fatto al fine di decidere se il design lungo queste linee.

Edit:Grazie per tutte le risposte finora sono abbastanza completi.Vorrei sapere una cosa: Come è che Windows sia a conoscenza del mio servizio?Posso gestire con il nativo di utilità di Windows? Che cosa è l'equivalente di mettere una start/stop script in /etc/init.d?

È stato utile?

Soluzione

Sì, è possibile.Io lo faccio usando il pythoncom librerie che vengono inclusi con ActivePython o può essere installato con pywin32 (Python per Windows estensioni).

Questo è uno scheletro di base per un servizio molto semplice:

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)

Il tuo codice dovrebbe andare in main() metodo—di solito con una sorta di loop infinito che potrebbe essere interrotta mediante il controllo di una bandiera, che si imposta nel SvcStop metodo

Altri suggerimenti

Anche se io con voto positivo la risposta scelta di un paio di settimane fa, nel frattempo ho faticato molto di più con questo argomento.Ci si sente come avere una speciale installazione di Python e l'utilizzo di speciali moduli per eseguire uno script come un servizio è semplicemente il modo sbagliato.Che cosa circa la portabilità e simili?

Mi sono imbattuto in questo meraviglioso Non succhiare il Gestore del Servizio, che ha reso davvero semplice e sano per affrontare con i Servizi di Windows.Ho pensato che dato che ho potuto passare le opzioni per servizio installato, ho potuto solo selezionare il mio eseguibile di Python e passare il mio script come opzione.

Non ho ancora provato questa soluzione, ma lo farò subito e aggiornare questo post lungo tutto il processo.Anche io sono interessato a usare virtualenvs su Windows, quindi potrei venire con un tutorial, prima o poi, e link ad esso qui.

Ci sono un paio di alternative per l'installazione come servizio per qualsiasi file eseguibile di Windows.

Metodo 1:Utilizzare instsrv e srvany da rktools.exe

Per Windows Home Server o Windows Server 2003 (funziona con WinXP troppo), il Windows Server 2003 Resource Kit Tools viene fornito con programmi di utilità che può essere utilizzato in tandem per questo, chiamato instsrv.exe e srvany.exe.Vedere questo articolo della Microsoft KB KB137890 per i dettagli su come usare questi utils.

Per Windows Home Server, c'è un grande utente amichevole wrapper per questi programmi di utilità chiamato giustamente "Qualsiasi Servizio Installer".

Metodo 2:Utilizzare ServiceInstaller per Windows NT

C'è un'altra alternativa che utilizza ServiceInstaller per Windows NT (scaricabile qui) con python istruzioni disponibili.Contrariamente al nome, funziona sia con Windows 2000 e Windows XP come bene.Qui ci sono alcune istruzioni su come installare uno script python come un servizio.

L'installazione di uno script Python

Eseguire ServiceInstaller per creare un nuovo servizio.(In questo esempio, è assunto che python è installato presso 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

Dopo l'installazione, aprire il Controllo Pannello l'applet Servizi, selezionare e avviare il PythonTest servizio.

Dopo la mia prima risposta, ho notato che c'erano strettamente correlati Q&A già pubblicato sul COSÌ.Vedere anche:

È possibile eseguire uno script Python come un servizio (in Windows)?Come?

Come faccio a fare in modo che Windows a conoscenza di un servizio che ho scritto in Python?

Il modo più semplice per raggiungere questo obiettivo è quello di utilizzare il native command sc.exe:

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

Riferimenti:

  1. https://technet.microsoft.com/en-us/library/cc990289(v=rovescio del lavoro.11).aspx
  2. Quando la creazione di un servizio con sc.exe come passare parametri di contesto?

Il modo più semplice è quello di utilizzare: Il nssm - Non Succhiare il Gestore del Servizio:

1 - fare il download su https://nssm.cc/download

2 - installare il programma in python come un servizio di:Vincere prompt come amministratore

c:>nssm.exe installare WinService

3 - NSSMs console:

percorso:C:\Python27\Python27.exe

Nella directory di avvio:C:\Python27

Argomenti:c:\WinService.py

4 - verifica del creato servizi su servizi.msc

Spiegazione passo passo come farlo funzionare :

1 - Prima di creare un file python secondo lo scheletro di base di cui sopra.E salvarlo in un percorso, ad esempio :"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 - A questo punto dobbiamo registrare il nostro servizio.

Eseguire il prompt dei comandi come amministratore tipo:

sc creare TestService binpath= "C:\Python36\Python.exe c:\PythonFiles\AppServerSvc.py" DisplayName= "TestService" start= auto

il primo argomento di binpath è il percorso di python.exe

il secondo argomento di binpath è il percorso del vostro file python che abbiamo creato già

Da non perdere che si dovrebbe mettere uno spazio dopo ogni "="segno.

Poi se tutto è ok, si dovrebbe vedere

[SC] CreateService SUCCESSO

Ora il python è installato come servizio di windows ora.Lo si può vedere nel Servizio di Gestione e del registro di sistema sotto :

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services estService

3 - Ok ora.È possibile avviare il servizio di service manager.

È possibile eseguire ogni file python che fornisce questo servizio scheletro.

Ho iniziato a ospitare un servizio con pywin32.

Tutto andava bene, ma ho incontrato il problema è che il servizio non è stato in grado di avviare entro 30 secondi (tempo di timeout predefinito per Windows) all'avvio del sistema.E ' stato fondamentale per me, perché di avvio di Windows ha avuto luogo simultanea su più macchine virtuali ospitate su una macchina fisica, e IO carico è stato enorme.Messaggi di errore sono:

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.

Ho combattuto molto con pywin, ma finì con utilizzando il nssm come è stato proposto in questa risposta.E ' stato molto facile migrazione.

Accettato di rispondere utilizzando win32serviceutil funziona, ma è complicato e rende il debug e le modifiche più difficile.È lontano più facile da usare il nssm (Non Succhiare il Gestore del Servizio).Si scrive e comodamente eseguire il debug di un normale programma in python e quando finalmente funziona, utilizzare il nssm installarlo come servizio in meno di un minuto:

Da un elevato (admin) prompt dei comandi eseguire nssm.exe install NameOfYourService e compilando le seguenti opzioni:

  • percorso:(il percorso python.exe ad es. C:\Python27\Python.exe)
  • Argomenti:(il percorso del vostro script python, ad esempio c:\path\to\program.py)

A proposito, se il vostro programma di stampa di messaggi di utilità che si desidera conservare in un file di log il nssm in grado di gestire anche questo e molto di più per voi.

Per chi desidera creare un servizio in VENV o Pycharm !!!!!!!

Dopo la lettura di tutti i anwsers e creare qualche script, se è possibile eseguire python service.py install e python service.py debug, ma python service.py start non ha risposta.

Forse è causato da venv problema, perché windows di inizio del servizio il servizio, exec PROJECT\venv\Lib\site-packages\win32\pythonservice.exe.

È possibile utilizzare powershell o cmd per testare il servizio per trovare più errore di dettagli.

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)

Se si ottiene qualche errore, come me, allora è possibile controllare la mia risposta a un'altra domanda, ho risolto e posto il mio codice qui.

il nssm in python 3+

(Ho convertito il mio .py file .exe con pyinstaller)

il nssm:come detto prima

  • eseguire il nssm installare {Nome}
  • Su NSSMs console:

    percorso: path o\your\program.exe

    Nella directory di avvio: percorso\a\di\ #stesso percorso ma senza il vostro program.exe

    Argomenti:vuoto

pysc: Servizio Controllo di Gestione su Python

Esempio di script per l'esecuzione come servizio tratto da 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()

Creare e avviare il servizio

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

Interrompere e cancellare servizio

import pysc

service_name = 'test_xmlrpc_server'

pysc.stop(service_name)
pysc.delete(service_name)
pip install pysc
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top