Nasıl Windows bir hizmet olarak bir Python komut dosyası çalıştırılır?

oy
211

Bir veritabanında saklanan çeşitli birbiriyle nesneler paylaşan bir dizi program için mimari çizim ediyorum. Ben bu nesnelerin üzerinde operasyonlar için daha yüksek bir seviyede arayüzü sağlayan bir hizmet ve bu hizmet üzerinden nesneleri erişmek için diğer programlar gibi davranmaya programlarından birini istiyorum.

Python ve teknolojileri olarak Django çerçevesi ile bu hizmeti uygulamak için şu anda hedefliyorum. Ben Linux Python program Artalanda nasıl anlamaya eminim. Ancak, sistem, Windows desteklemelidir isteğe bağlı bir Spec öğedir. Windows programlama ve Windows hizmetleri ile hiçbir deneyime sahip çok az deneyime sahip.

O (yani kullanıcı girişi olmadan otomatik olarak çalıştırın) bir Windows hizmeti olarak bir Python programları çalıştırmak mümkün mü? Ben mutlaka bu bölümü uygulamak zorunda olmayacak, ama bu satırlar boyunca tasarım karar vermek amacıyla yapılabilir nasıl bir fikir gerekir.

Düzenleme: tüm cevaplar için teşekkürler şimdiye kadar, onlar oldukça kapsamlıdır. Bir şey daha öğrenmek istiyorum: Nasıl, Windows Hizmetimde farkındadır? Bunun doğal Windows ekipmana sahip yönetebilir mi? /etc/init.d bir start / stop komut koyarak eşdeğer nedir?

Oluştur 28/08/2008 saat 13:28
kaynak kullanıcı
Diğer dillerde...                            


12 cevaplar

oy
220

Evet yapabilirsin. Bunun ile birlikte gelir pythoncom kütüphaneleri kullanılarak do ActivePython veya monte edilebilir pywin32 (Windows uzantıları için Python).

Bu basit bir hizmet için temel bir iskelet:

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)

Kodunuz içinde giderdim main()sen belirlenen bir bayrak, kontrol ederek kesintiye uğrayabilir sonsuz döngüye çeşit yöntem-genellikle SvcStopyöntemle

Cevap 28/08/2008 saat 13:39
kaynak kullanıcı

oy
23

neredeyse bir hizmet herhangi bir Windows çalıştırılabilir olarak yüklemek için birkaç alternatifi vardır.

rktools.exe kullan instsrv ve srvany: Yöntem 1

Windows Home Server veya Windows Server 2003 (çok WinXP ile çalışır) için, Windows Server 2003 Kaynak Seti Araçları bunun için tandem kullanılabilecek yardımcı programlar denilen ile gelir Instsrv.exe ve Srvany.exe . Microsoft KB makalesi Bkz KB137890 bu utils'i nasıl kullanılacağına ilişkin ayrıntılar için.

Windows Home Server için "zaten adı bu programları için mükemmel bir kullanıcı dostu sarıcı var Herhangi Servis Installer ".

Yöntem 2: Windows NT için kullanın serviceInstaller

Kullanarak başka bir alternatif yoktur Windows NT için serviceInstaller ( indirme-muktedir burada ) ile mevcut piton talimatlar . Adının aksine, Windows 2000 ve Windows XP hem de her ikisi ile çalışır. İşte bir hizmet olarak bir python komut yükleme için bazı talimatlar bulunmaktadır.

Python komut dosyası yükleme

yeni bir hizmet oluşturmak için serviceInstaller çalıştırın. (Piton c yüklü bu örnekte, varsayılır: \ 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

yükledikten sonra, Denetim Masası'nın Hizmetler uygulamasını açın seçip PythonTest hizmetini başlatın.

Benim ilk cevap sonra, yakından ilişkili Q & A zaten SO yayınlanan olduğunu fark ettim. Ayrıca bakınız:

Ben (Windows'ta) bir hizmet olarak bir Python komut dosyası çalıştırabilir miyim? Nasıl?

Nasıl Python içinde yazdım bir hizmetin, Windows farkında yapabilirim?

Cevap 28/02/2009 saat 07:30
kaynak kullanıcı

oy
28

Ben birkaç hafta geri seçilen cevabı upvoted rağmen, bu arada bu konu ile çok daha fazla mücadele etti. Bu özel bir Python kurulumu sahip ve bir hizmet sadece yanlış bir yoldur gibi bir komut dosyası çalıştırmak için özel modülleri kullanarak gibi hissediyor. Ne taşınabilirlik ve bu tür hakkında?

Ben harika tökezledi Sigara emme Servis Yöneticisi , Windows Services başa gerçekten basit ve aklı başında yapılmış olan. Ben yüklü bir hizmet için seçenekler geçebileceği beri, ben sadece benim de Python çalıştırılabilir seçin ve bir seçenek olarak benim komut geçebileceği düşündüm.

Henüz bu çözümü denemedim ama çok doğru şimdi yapmak ve süreç boyunca bu yazı güncelleyecektir. Ayrıca Windows üzerinde virtualenvs kullanarak ilgileniyorum, bu yüzden burada buna bir öğretici ile er ya da geç ve bağlantı kadar gelebilir.

Cevap 28/07/2014 saat 12:41
kaynak kullanıcı

oy
11

Bu başarmak için en basit yolu yerli komut SC.exe yardımcı kullanmaktır:

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 ile bir servis yaratmak; bağlam parametrelerinde geçmesine nasıl
Cevap 07/12/2016 saat 10:23
kaynak kullanıcı

oy
-2

PYSc: Python üzerinde Hizmet Denetim Yöneticisi

Örnek komut bir hizmet olarak çalıştırmak için pythonhosted.org alınan :

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

Oluşturma ve hizmetini başlatmak

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

Dur ve hizmetini silmek

import pysc

service_name = 'test_xmlrpc_server'

pysc.stop(service_name)
pysc.delete(service_name)
pip install pysc
Cevap 03/03/2017 saat 18:29
kaynak kullanıcı

oy
7

İşe yaraması için nasıl adım açıklama adım:

1- Öncelikle yukarıda bahsedilen temel iskeletine göre bir piton dosyası oluşturun. Ve örneğin bir yola kaydetmek: "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 - Bu adımda biz hizmetimizi kayıt edilmelidir.

Olarak Komut istemini çalıştırın yönetici gibi yazın:

SC = Testservice binpath oluşturmak ": \ Python36 \ python.exe c: C \ PythonFiles \ AppServerSvc.py" GörünenAd = "Testservice" = otomatik başlatmak

ilk argüman binpath olan python.exe yolu

ikinci argüman binpath olan senin piton dosyasının yolunu biz zaten oluşturulmuş

Her "sonra bir boşluk koymak gerektiğini kaçırmayın = " işareti.

herşey yolunda Sonra, sen görmelisiniz

[SC] CreateService BAŞARILI

Şimdi piton servisi artık windows hizmeti olarak yüklenir. Sen Servis Yöneticisi ve kayıt altına görebiliyorum:

\ CurrentControlSet \ Services HKEY_LOCAL_MACHINE \ SYSTEM \ Testservice

Şimdi 3- Ok. Sen hizmet yöneticisi hizmetinizin başlayabilirsiniz.

Bu hizmet iskeletini sağlayan her piton dosyasını yürütebilirsiniz.

Cevap 29/06/2017 saat 07:37
kaynak kullanıcı

oy
3

: Basit yolu kullanmaktır NSSM - Sigara Sucking Hizmet Yöneticisi:

1 - indirilmiş dosyayı yapmak https://nssm.cc/download

2 - bir hizmet olarak piton programı yüklemek: Win yönetici olarak istemi

c:> nssm.exe yüklemek WinService

3 - NSSM's konsolunda:

yol: C: \ Python27 \ Python27.exe

Başlangıç ​​dizini: C: \ Python27

Bağımsız değişkenler: C: \ WinService.py

4 - services.msc üzerinde oluşturulan servisleri kontrol

Cevap 27/09/2017 saat 13:05
kaynak kullanıcı

oy
2

Ben bir hizmet olarak barındırma başladı pywin32 .

Her şey iyi ama hizmet Sistem açılışında 30 saniye (Windows için varsayılan zaman aşımı) içinde başlamak mümkün değildi sorunu araya geldi. Windows başlangıç ​​bir fiziksel makine üzerinde barındırılan birçok sanal makinelerde eş zamanlı gerçekleşti çünkü benim için çok önemliydi ve IO yük çok büyük. Hata mesajları vardı:

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.

Ben pywin ile çok savaştı ama önerilmişti olarak NSSM kullanarak ile sona erdi bu cevap . Ona göç etmek çok kolaydı.

Cevap 12/10/2018 saat 12:07
kaynak kullanıcı

oy
0

Kullanılarak kabul cevap win32serviceutilama işler karmaşık ve hata ayıklama yapar ve daha sert değiştirir. Öyle uzak NSSM (kullanımı daha kolay olmayan Sucking Servis Yöneticisi) . Sen yazmak ve konforlu normal bir piton programı hata ayıklama ve nihayet çalışır zaman bir dakikadan az bir hizmet olarak yüklemek için NSSM kullanın:

Bir yükseltilmiş (yönetici) komut isteminden çalıştırmak nssm.exe install NameOfYourServiceve fill-in bu seçeneklerden:

  • yol : (yol python.exe örneğin C:\Python27\Python.exe)
  • Argümanlar : (sizin piton komut yolu, örneğin c:\path\to\program.py)

Bu arada, bir günlük dosyasında saklamak istediğiniz kullanışlı program baskılar mesajları NSSM da sizin için bu ve çok daha fazla işleyebilir eğer.

Cevap 10/11/2018 saat 13:52
kaynak kullanıcı

oy
0

Herkes VENV veya pycharm hizmet oluşturmak isteyen !!!!!!!

Ve tüm anwsers okuduktan sonra çalıştırabileceğiniz, bazı komut dosyaları oluşturmak python service.py installve python service.py debugfakat python service.py starthiçbir yanıt vardır.

Windows hizmet exec ederek hizmetini başlatmak Belki bunun sebebi, venv sorundan sebep oldu PROJECT\venv\Lib\site-packages\win32\pythonservice.exe.

Sen kullanabilirsiniz powershellveya cmddaha fazla hatanın ayrıntılarını bulmak için hizmetinizi test etmek.

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)

Eğer benim gibi bazı hata alırsanız, o zaman ben düzelttim, bir başka soru sorulabilir Cevabımı kontrol edebilir ve kodumu sonrası burada .

Cevap 29/05/2019 saat 07:57
kaynak kullanıcı

oy
0

Python üzerine NSSM 3+

(Ben pyinstaller ile .exe benim .py dosyasını dönüştürülmüş)

NSSM: daha önce sözü geçen şekilde

  • NSSM çalıştırmak yüklemek {ServiceName}
  • NSSM's konsolunda:

    yol: yol \ sizin \ Program.exe \ olarak

    Başlangıç dizini: yol \ yolu olarak ancak Program.exe olmadan \ #same \ olarak

    Argümanlar: Boş

Cevap 04/06/2019 saat 23:42
kaynak kullanıcı

oy
0

halka veya subthread eksiksz pywin32 Örnek

birkaç gün açılıp bu konuda çalıştıktan sonra burada hoş tutmak için PyWin32 kullanarak bulmak isterdi ve müstakil cevaptır.

Bu, bir göre loop ve bir iplik tabanlı bir çözüm için tam bir çalışma kodudur. Ben sadece 2,7 ve Win7 üzerinde son sürümünü test ettik rağmen, piton 2 ve 3 hem çalışabilir. Döngü yoklama kodu için iyi olmalı ve taban fazla sunucu benzeri kodla çalışmalıdır. O ile güzel iş gibi görünüyor garson incelikle kapatmaya standart bir yol yoktur WSGI sunucusunda.

Ayrıca nota gibi, orada örnekler yükleri gibi görünüyor ki gibi bu neredeyse faydalıdır, ancak kesim ve körlemesine yapıştırılan diğer örnekler var çünkü gerçekte, yanıltıcı söyledi. Yanlış olabilirim. bunun için beklemek asla ama eğer neden bir olay yaratmak?

Yani ben hala özellikle iplik sürümden çıkış ne kadar temiz açısından, burada biraz kaygan bir zeminde değilim, ama en azından bir şey olduğuna inanıyorum hissediyorum söyledi yanıltıcı burada.

basitçe bir dosyaya kodu kopyalayıp ve talimatları uygulayın çalıştırın.

# 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()
Cevap 26/01/2020 saat 22:52
kaynak kullanıcı

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