Pregunta

Yo estoy perfilando la arquitectura de un conjunto de programas que comparten distintos interrelacionados objetos almacenados en una base de datos.Yo quiero uno de los programas de actuar como un servicio que proporciona un nivel superior de la interfaz para las operaciones sobre estos objetos, y de los otros programas para obtener acceso a los objetos a través de ese servicio.

Actualmente estoy buscando Python y Django framework, como el de las tecnologías a implementar ese servicio.Estoy bastante seguro de que la figura de cómo daemonize el programa de Python en Linux.Sin embargo, es opcional especificaciones elemento que el sistema de soporte de Windows.Tengo poca experiencia con la programación de Windows y ninguna experiencia con los servicios de Windows.

Es posible ejecutar un programas de Python como un servicio de Windows (me.e.ejecutar de forma automática, sin inicio de sesión de usuario)? Yo no necesariamente tiene que implementar esta parte, pero tengo una idea aproximada de cómo se llevaría a cabo con el fin de decidir si el diseño a lo largo de estas líneas.

Editar:Gracias por todas las respuestas hasta el momento, son bastante completas.Me gustaría saber una cosa más: Cómo es Windows consciente de mi servicio?Puedo manejar con el nativo de Windows utilidades? ¿Cuál es el equivalente de poner una start/stop script en /etc/init.d?

¿Fue útil?

Solución

Sí, sí puede.Yo lo hago usando el pythoncom bibliotecas que vienen incluidos con ActivePython o puede ser instalado con pywin32 (Python para Windows extensions).

Este es un esquema básico para un servicio sencillo:

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)

El código iría en la main() método—por lo general con algún tipo de bucle infinito que puede ser interrumpido por la comprobación de una bandera, que se establece en el SvcStop método

Otros consejos

Aunque yo upvoted la respuesta un par de semanas atrás, en el mientras tanto he luchado mucho más con este tema.Se siente como tener un especial para la instalación de Python y el uso de módulos especiales para ejecutar una secuencia de comandos como un servicio es simplemente el camino equivocado.¿Qué acerca de la portabilidad y tal?

Me encontré con la maravillosa No chupar el Administrador del Servicio de, que hace que sea muy simple y sano para lidiar con los Servicios de Windows.Pensé que ya podía pasar opciones a un servicio instalado, yo podría muy bien seleccione mi ejecutable de Python y pasar mi script como una opción.

Todavía no he probado esta solución, pero voy a hacerlo ahora mismo y la actualización de este post a lo largo del proceso.Yo también estoy interesado en el uso de virtualenvs en Windows, por lo que podría venir para arriba con un tutorial más pronto o más tarde, y un enlace a ella aquí.

Hay un par de alternativas para la instalación como un servicio prácticamente cualquier ejecutable de Windows.

Método 1:Uso instsrv y srvany de rktools.exe

Para Windows Home Server o Windows Server 2003 (funciona con WinXP demasiado), la Windows Server 2003 Herramientas Del Kit De Recursos viene con utilidades que puede ser utilizado en tándem para esto, se llama instsrv.exe y srvany.exe.Consulte este artículo de Microsoft KB KB137890 para obtener detalles sobre cómo utilizar estas utilidades.

Para Windows Home Server, hay una gran amigable para el usuario contenedor para estas utilidades denominado acertadamente "Cualquier Instalador De Servicio".

Método 2:Uso ServiceInstaller para Windows NT

No hay otra alternativa que el uso de ServiceInstaller para Windows NT (puede ser descargado aquí) con python instrucciones disponibles.Contrariamente al nombre, funciona con Windows 2000 y Windows XP así.Aquí están algunas instrucciones sobre cómo instalar un script de python como un servicio.

La instalación de una secuencia de comandos de Python

Ejecutar ServiceInstaller para crear una nueva servicio.(En este ejemplo, es supone que python está instalado en 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

Después de la instalación, abra el Control de Panel del subprograma de Servicios, seleccionar y iniciar el PythonTest servicio.

Después de mi primera respuesta, me di cuenta de que estaban estrechamente relacionados con el Q&A ya publicado en ASÍ.Vea también:

Puedo ejecutar una secuencia de comandos de Python como un servicio (en Windows)?Cómo?

¿Cómo puedo hacer que Windows consciente de un servicio que he escrito en Python?

La manera más simple de lograr esto es utilizar los comandos nativos sc.exe:

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

Referencias:

  1. https://technet.microsoft.com/en-us/library/cc990289(v=ws.11).aspx
  2. Al crear un servicio con sc.exe cómo pasar en el contexto de los parámetros?

La forma más sencilla es utilizar el: NSSM - la No Chuparse el Administrador de Servicios:

1 - hacer la descarga en https://nssm.cc/download

2 - instalar el programa en python como un servicio:Ganar símbolo del sistema como administrador

c:>nssm.exe instalar WinService

3 - En NSSMs de la consola:

ruta de acceso:C:\Python27\Python27.exe

Directorio de inicio:C:\Python27

Argumentos:c:\WinService.py

4 - comprobar que los servicios creados en los servicios.msc

Explicación paso a paso de cómo hacer que funcione :

1 - en Primer lugar crear un archivo de python según el esqueleto básico mencionado anteriormente.Y guardarlo en una ruta, por ejemplo :"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 - En este paso debemos registrar nuestro servicio.

Ejecutar el símbolo del sistema como administrador y el tipo como:

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

el primer argumento de binpath es el camino de la python.exe

segundo argumento de binpath es la ruta de acceso del archivo de python que hemos creado ya

No te pierdas que usted debe poner un espacio después de cada "="la señal.

Entonces, si todo está bien, debería ver

[SC] CreateService ÉXITO

Ahora tu python está instalado como servicio de windows ahora.Se puede ver en el Administrador del Servicio de registro y de bajo :

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services estService

3 - Ok ahora.Usted puede comenzar su servicio en el administrador del servicio.

Puede ejecutar cada archivo de python que proporciona este servicio esqueleto.

Empecé hosting como un servicio con pywin32.

Todo estaba bien, pero me encontré con el problema de que el servicio no fue capaz de iniciar dentro de los 30 segundos (tiempo de espera predeterminado para Windows) en el inicio del sistema.Era importante para mí, porque de inicio de Windows llevó a cabo simultánea en varias máquinas virtuales alojadas en una máquina física, y la carga de e / s fue enorme.Mensajes de Error fueron:

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.

He luchado mucho con pywin, pero terminó con el uso de NSSM como se propuso en esta respuesta.Fue muy fácil para migrar a ella.

El aceptó respuesta usando win32serviceutil funciona, pero es complicado y hace que la depuración y los cambios más difícil.Es ahora más fácil de usar NSSM (la No-Chupar el Administrador del Servicio).Escribir y cómodamente depuración normal programa en python y cuando finalmente los trabajos de utilizar NSSM para instalarlo como un servicio en menos de un minuto:

Con privilegios elevados (admin) símbolo del sistema ejecute nssm.exe install NameOfYourService y lo llena en estas opciones:

  • camino:(la ruta de acceso a python.exe por ejemplo, C:\Python27\Python.exe)
  • Argumentos:(la ruta de acceso a la secuencia de comandos de python, por ejemplo, c:\path\to\program.py)

Por cierto, si el programa imprime mensajes útiles que se desea mantener en un archivo de registro NSSM también puede manejar esto y mucho más para usted.

Para cualquier persona que desea crear el servicio en VENV o Pycharm !!!!!!!

Después de leer todas las respuestas y crear algunos de guiones, si puede ejecutar python service.py install y python service.py debug, pero python service.py start no tiene respuesta.

Tal vez es causada por venv problema, debido a que el servicio de windows de inicio de su servicio exec PROJECT\venv\Lib\site-packages\win32\pythonservice.exe.

Puede utilizar powershell o cmd para probar su servicio para encontrar el error más detalles.

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)

Si usted recibe algún error como yo, entonces usted puede comprobar mi respuesta en otra pregunta, me fijo y post mi código aquí.

nssm en python 3+

(He transformado mi .py archivo .exe con pyinstaller)

nssm:como se dijo antes

  • ejecutar nssm instalar {ServiceName}
  • En NSSMs de la consola:

    ruta de acceso: path o\your\program.exe

    Directorio de inicio: ruta de acceso\a\su\ #lo mismo que la ruta de acceso, pero sin su program.exe

    Argumentos:vacío

pysc: Administrador de Control de servicios en Python

Ejemplo de script para que se ejecute como un servicio tomado de 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()

Crear e iniciar el servicio

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

Detener y eliminar el servicio

import pysc

service_name = 'test_xmlrpc_server'

pysc.stop(service_name)
pysc.delete(service_name)
pip install pysc
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top