आप विंडोज में सेवा के रूप में पायथन स्क्रिप्ट कैसे चलाते हैं?


272

मैं प्रोग्राम के एक सेट के लिए वास्तुकला को स्केच कर रहा हूं जो एक डेटाबेस में संग्रहीत विभिन्न परस्पर संबंधित वस्तुओं को साझा करता है। मैं प्रोग्रामों में से एक को एक सेवा के रूप में कार्य करना चाहता हूं जो इन वस्तुओं पर परिचालन के लिए एक उच्च स्तरीय इंटरफ़ेस प्रदान करता है, और अन्य कार्यक्रमों को उस सेवा के माध्यम से वस्तुओं तक पहुंचने के लिए।

मैं वर्तमान में उस सेवा को लागू करने के लिए पायथन और Django ढांचे के लिए तकनीकों के रूप में लक्ष्य बना रहा हूं। मुझे पूरा यकीन है कि मैं लिनक्स में पायथन प्रोग्राम को निष्क्रिय करने का तरीका बताता हूं। हालाँकि, यह एक वैकल्पिक युक्ति है जिसे सिस्टम को Windows का समर्थन करना चाहिए। मुझे विंडोज़ प्रोग्रामिंग के साथ बहुत कम अनुभव है और विंडोज़ सेवाओं के साथ बिल्कुल भी कोई अनुभव नहीं है।

क्या पायथन कार्यक्रमों को विंडोज सेवा के रूप में चलाना संभव है (यानी उपयोगकर्ता लॉगिन के बिना इसे स्वचालित रूप से चलाना)? मुझे इस हिस्से को लागू करने की आवश्यकता नहीं होगी, लेकिन मुझे एक मोटे विचार की आवश्यकता है कि यह कैसे तय किया जाए ताकि इन पंक्तियों के साथ डिजाइन किया जा सके।

संपादित करें: अब तक के सभी उत्तरों के लिए धन्यवाद, वे काफी व्यापक हैं। मैं एक और बात जानना चाहूंगा: विंडोज को मेरी सेवा के बारे में कैसे पता है? क्या मैं इसे देशी विंडोज उपयोगिताओं के साथ प्रबंधित कर सकता हूं? /Etc/init.d में स्क्रिप्ट / स्टॉप स्क्रिप्ट डालने के बराबर क्या है?

जवाबों:


260

हाँ तुम कर सकते हो। मैं इसे pythoncom पुस्तकालयों का उपयोग करके करता हूं जो ActivePython के साथ आते हैं या pywin32 (विंडोज एक्सटेंशन के लिए पायथन) के साथ इंस्टॉल किए जा सकते हैं ।

यह एक साधारण सेवा के लिए एक बुनियादी कंकाल है:

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विधि में सेट किया है


24
इसे कोड करने के बाद, मैं इसे सेवा के रूप में चलाने के लिए विंडोज को कैसे बताऊं?
किट

34
@ किट: पैरामीटर "इंस्टॉल" के साथ कमांड लाइन से अपनी स्क्रिप्ट चलाएं। तब आप अपने एप्लिकेशन को विंडोज की सेवाओं की सूची में देख पाएंगे, जहां आप इसे शुरू कर सकते हैं, इसे रोक सकते हैं, या इसे स्वचालित रूप से शुरू करने के लिए सेट कर सकते हैं
रिकार्डो रीस

17
आप अजगर का विशेष उल्लेख करते हैं, और आप इसे अपने उदाहरण कोड में आयात करते हैं। समस्या यह है कि आप वास्तव में कभी भी अपने उदाहरण कोड में कहीं भी अजगर का उपयोग नहीं करते हैं, आप केवल इसे आयात करते हैं। इसे विशेष उल्लेख क्यों दें और फिर इसका उपयोग न करें?
बटंस Butt४०

11
के लिए क्यों socket.setdefaulttimeout(60)है? क्या यह किसी सेवा के लिए आवश्यक है, या क्या यह केवल किसी मौजूदा सेवा से कॉपी की गई आकस्मिक थी? :)
तैमूर

7
chrisumbel.com/article/windows_services_in_python यह एक ऐसा ही उदाहरण है, लेकिन अधिक पूर्ण
csprabala

43

हालाँकि मैंने कुछ हफ़्ते पहले चुने गए उत्तर को वापस ले लिया, इस बीच मैंने इस विषय के साथ बहुत अधिक संघर्ष किया। ऐसा लगता है कि एक विशेष पायथन इंस्टॉलेशन होने और स्क्रिप्ट को चलाने के लिए विशेष मॉड्यूल का उपयोग करना एक सेवा के रूप में बस गलत तरीका है। पोर्टेबिलिटी और इस तरह के बारे में क्या?

मैं अद्भुत गैर-चूसने वाले सेवा प्रबंधक से टकरा गया , जिसने विंडोज सेवाओं से निपटने के लिए वास्तव में सरल और समझदार बना दिया। मुझे लगा कि जब मैं एक स्थापित सेवा के लिए विकल्प पारित कर सकता हूं, तो मैं अपने पायथन निष्पादन योग्य का चयन कर सकता हूं और एक विकल्प के रूप में अपनी स्क्रिप्ट पास कर सकता हूं।

मैंने अभी तक इस समाधान की कोशिश नहीं की है, लेकिन मैं अभी ऐसा करूंगा और इस पोस्ट को प्रक्रिया के साथ अपडेट करूंगा। मुझे विंडोज़ पर वर्चुअन का उपयोग करने में भी दिलचस्पी है, इसलिए मैं जल्द या बाद में एक ट्यूटोरियल के साथ आ सकता हूं और इसे यहां लिंक कर सकता हूं।


कोइ भाग्य? मैं एक ग्राहक के लिए एक बहुत ही सरल साइट बना रहा हूं और पूरे अपाचे स्टैक का उपयोग करने की आवश्यकता नहीं है। स्वयं द्वारा सेवा का निर्माण भी मुसीबत के लिए एक निमंत्रण की तरह लग रहा है, जैसा कि मैंने अन्य टिप्पणियों से पढ़ा है।
जरण

हां, यह काम करता है और इसे करना बहुत आसान है। आप सिर्फ स्क्रिप्ट के लिए रास्ता और तर्क देते हैं। मैं किसी भी तरह से कंसोल विंडो के साथ समाप्त होने की स्थिति में एक कंसोल के साथ चलाने के लिए मेरा प्राप्त करने में सक्षम था।
किमीगुएर

जब यह स्पष्ट रूप से काम करता है, तो विशेष रूप से अन्य कठिनाइयां होती हैं, जब आपको "पूरे अपाचे स्टैक का उपयोग करने की आवश्यकता नहीं होती है": उदाहरण के लिए gunicorn अभी तक विंडोज पर नहीं चलता है, जो वास्तव में मेरे लिए शोस्टॉपर था।
mknaf

4
की तरह "\ अस्थायी \ myscript.py स्थापित nssm MyServiceName c::: \ python27 \ python.exe ग" चाल यहाँ एक सेवा और पैरामीटर के रूप में अपने अजगर स्क्रिप्ट के रूप में python.exe चलाने के लिए है
poleguy

बहुत अच्छा काम करता है! कई वर्चुअल वातावरण वाले सिस्टम पर, पथ वांछित वर्चुअल वातावरण की स्क्रिप्ट निर्देशिका में पायथन दुभाषिया निर्वासित को संदर्भित कर सकता है। ऐसा लगता है जैसे new-servicePowerShell को ऐसा करने में सक्षम होना चाहिए, लेकिन एक सेवा के रूप में एक स्क्रिप्ट शुरू करना (और निगरानी करना) स्पष्ट रूप से बहुत अधिक विवरण शामिल करता है, जो nssm बहुत अच्छी तरह से देखभाल करता है।
फ्रेड श्लेफर

33

सबसे सरल तरीका है: एनएसएसएम - गैर-चूसने वाला सेवा प्रबंधक। बस अपने चयन के स्थान पर डाउनलोड और अनज़िप करें। यह एक स्व-निहित उपयोगिता है, लगभग 300KB (इस उद्देश्य के लिए पूरे pywin32 सुइट को स्थापित करने की तुलना में बहुत कम) और किसी भी "स्थापना" की आवश्यकता नहीं है। ज़िप में 64-बिट और उपयोगिता का 32-बिट संस्करण है। या तो वर्तमान प्रणालियों पर अच्छा काम करना चाहिए (आप 64-बिट सिस्टम पर सेवाओं का प्रबंधन करने के लिए 32-बिट संस्करण का उपयोग कर सकते हैं)।

जीयूआई दृष्टिकोण

1 - अजगर कार्यक्रम को सेवा के रूप में स्थापित करें। व्यवस्थापक के रूप में एक विन प्रॉम्प्ट खोलें

c:\>nssm.exe install WinService

2 - एनएसएसएम के जीयूआई कंसोल पर:

पथ: C: \ Python27 \ Python27.exe

स्टार्टअप निर्देशिका: C: \ Python27

तर्क: c: \ WinService.py

3 - services.msc पर बनाई गई सेवाओं की जाँच करें

स्क्रिप्टिंग दृष्टिकोण (कोई जीयूआई नहीं)

यह आसान है अगर आपकी सेवा एक स्वचालित, गैर-संवादात्मक प्रक्रिया का हिस्सा होनी चाहिए, जो आपके नियंत्रण से परे हो सकती है, जैसे कि बैच या इंस्टॉलर स्क्रिप्ट। यह माना जाता है कि आदेशों को प्रशासनिक विशेषाधिकारों के साथ निष्पादित किया जाता है।

सुविधा के लिए यहां केवल उपयोगिता का हवाला देकर आदेशों का वर्णन किया गया है nssm.exe। यह सलाह दी जाती है, हालांकि, इसे अपने पूर्ण पथ के साथ स्क्रिप्टिंग में अधिक स्पष्ट रूप से संदर्भित करने के लिए c:\path\to\nssm.exe, क्योंकि यह एक आत्म-निहित निष्पादन योग्य है जो एक निजी पथ में स्थित हो सकता है जिसे सिस्टम के बारे में पता नहीं है।

1. सेवा स्थापित करें

आपको सेवा के लिए एक नाम निर्दिष्ट करना होगा, उचित पायथन निष्पादन योग्य पथ और स्क्रिप्ट का पथ:

nssm.exe install ProjectService "c:\path\to\python.exe" "c:\path\to\project\app\main.py"

अधिक स्पष्ट रूप से:

nssm.exe install ProjectService 
nssm.exe set ProjectService Application "c:\path\to\python.exe"
nssm.exe set ProjectService AppParameters "c:\path\to\project\app\main.py"

वैकल्पिक रूप से आप अपने पायथन ऐप को पायथन मॉड्यूल के रूप में शुरू कर सकते हैं। एक आसान तरीका यह है कि nssm को बताएं कि इसे उचित प्रारंभिक निर्देशिका में बदलने की आवश्यकता है, जैसा कि आप कमांड कमांड से लॉन्च करते समय खुद करेंगे।

nssm.exe install ProjectService "c:\path\to\python.exe" "-m app.main"
nssm.exe set ProjectService AppDirectory "c:\path\to\project"

यह दृष्टिकोण आभासी वातावरण और स्व-निहित (एम्बेडेड) पायथन इंस्टॉल के साथ अच्छी तरह से काम करता है। बस उन तरीकों में सामान्य तरीकों से किसी भी पथ मुद्दों को ठीक से हल करना सुनिश्चित करें। nssm के पास जरूरत पड़ने पर पर्यावरण चर (जैसे PYTHONPATH) सेट करने का एक तरीका है, और बैच स्क्रिप्ट भी लॉन्च कर सकता है।

2. सेवा शुरू करने के लिए

nssm.exe start ProjectService 

3. सेवा बंद करने के लिए

nssm.exe stop ProjectService

4. सेवा को हटाने के लिए , confirmइंटरैक्टिव पुष्टि को छोड़ने के लिए पैरामीटर निर्दिष्ट करें ।

nssm.exe remove ProjectService confirm

मैंने nssm.exe का उपयोग अपने विजुअल स्टूडियो C ++। Exe को सेवा के रूप में स्थापित करने के लिए किया था, और अब मैं nssm.exe के साथ-साथ अपने पायथन .pyc को सेवा के रूप में उपयोग कर सकता हूं। धन्यवाद।
एटोरिकी

नोट: यदि आपकी * .py स्क्रिप्ट स्थान के साथ एक फ़ोल्डर में स्थित है (उदाहरण के लिए: C: \ Program Files \ myapp.py) को उद्धरण में तर्क निर्दिष्ट करने की आवश्यकता है: तर्क: "C: \ Program Files \ myapp.py"
Yury कोज़लोव

आभासी वातावरण कैसे प्रदान करें?
शीक मोईद

अधिक समय ढीला न करें और एनएसएसएम दृष्टिकोण के लिए जाएं। आभासी वातावरण के लिए, आपको केवल virtualenv फ़ोल्डर के अंदर अजगर निष्पादन योग्य को इंगित करना होगा।
गुस्तावो गोंकालेव्स

23

वस्तुतः किसी भी विंडोज़ निष्पादन योग्य सेवा के रूप में स्थापित करने के लिए कुछ विकल्प हैं।

विधि 1: rktools.exe से instrrv और srvany का उपयोग करें

विंडोज होम सर्वर या विंडोज सर्वर 2003 (WinXP के साथ भी काम करता है) के लिए, विंडोज सर्वर 2003 रिसोर्स किट टूल्स उपयोगिताओं के साथ आता है जिन्हें इसके लिए उपयोग किया जा सकता है, जिन्हें instsrv.exe और srvany.exe कहा जाता है । इन बर्तनों का उपयोग करने के तरीके के बारे में जानकारी के लिए यह Microsoft KB आलेख KB137890 देखें।

विंडोज होम सर्वर के लिए, इन उपयोगिताओं के लिए एक महान उपयोगकर्ता के अनुकूल आवरण है जिसे aptly " Any Service Installer " नाम दिया गया है ।

विधि 2: Windows NT के लिए ServiceInstaller का उपयोग करें

Windows NT के लिए ServiceInstaller ( यहाँ पर सक्षम है ) के साथ एक और विकल्प उपलब्ध है, जिसमें अजगर निर्देश उपलब्ध हैं । नाम के विपरीत, यह विंडोज 2000 और विंडोज एक्सपी दोनों के साथ काम करता है। एक सेवा के रूप में अजगर स्क्रिप्ट को कैसे स्थापित किया जाए, इसके लिए यहां कुछ निर्देश दिए गए हैं।

पायथन लिपि को स्थापित करना

नई सेवा बनाने के लिए ServiceInstaller चलाएं। (इस उदाहरण में, यह माना जाता है कि अजगर 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

इंस्टॉल करने के बाद, कंट्रोल पैनल की सर्विसेज एप्लेट को खोलें, पाइथनटेस्ट सर्विस को चुनें और शुरू करें।

मेरे प्रारंभिक उत्तर के बाद, मैंने देखा कि एसओ पर पहले से ही संबंधित प्रश्नोत्तर थे। यह सभी देखें:

क्या मैं एक सेवा (विंडोज में) के रूप में पायथन स्क्रिप्ट चला सकता हूं? कैसे?

मैं पायथन में लिखी गई एक सेवा के बारे में विंडोज से अवगत कैसे करूँ?


मैंने अभी देखा कि इसी तरह के अन्य प्रश्नोत्तर पहले से ही हैं: stackoverflow.com/questions/32404/… stackoverflow.com/questions/34328/…
popcnt

सर्विस इंस्टॉलर 64 बिट आर्किटेक्चर पर काम नहीं करता है इसलिए विकल्प 1 गोटो विकल्प बन जाता है।
नूह कैम्पबेल

ServiceInstaller के लिए उपरोक्त लिंक अब काम नहीं करता है। मैंने इसे यहां पाया: sites.google.com/site/conort/…
LarsH

2
ध्यान दें, मुझे नहीं लगता NTकि यह आवश्यक रूप से नाम के विपरीत होगा, कम से कम प्रोग्रामर-लोक भाषण में नहीं। यह सिर्फ "NT आर्किटेक्चर " को संदर्भित करता है , जैसा कि "NT ब्रांड " के विपरीत है । कहा कि विकिपीडिया पर बात करने के अनुसार, यह बहस पर निर्भर है, क्योंकि "यह एक आधिकारिक Microsoft शब्द नहीं है", लेकिन इस विचारधारा के साथ अभी भी एक परंपरा है।
n611x007

23

इसे प्राप्त करने का सबसे सरल तरीका देशी कमांड 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 के साथ एक सेवा बनाते समय संदर्भ मापदंडों में कैसे पारित करें?

मुझे लगता है, यह आपके आदेश या एप्लिकेशन के साथ एक समस्या है। फिर भी, इस support.microsoft.com/en-us/help/886695/…
pyOwner

मेरा ऐप सेवा के बाहर ठीक काम करता है, और मैंने बिना किसी परिणाम के एक ही कोड का उपयोग किया।
नीमरेशम

आभासी वातावरण कैसे प्रदान करें?
शीक मोईद

क्या आपने virtualenv की कोशिश की?
pyOwner 10

3
यह काम नहीं करता है। एक Windows सेवा को एक निश्चित इंटरफ़ेस को उजागर करना चाहिए जो pywin32 पैकेज करता है। हालाँकि, एक पुरानी-पुरानी पायथन लिपि पर्याप्त नहीं होगी।
सिद्धार्थ गांधी

17

कदम से कदम स्पष्टीकरण यह कैसे काम करने के लिए:

1- पहले ऊपर बताए गए बुनियादी कंकाल के अनुसार एक अजगर फ़ाइल बनाएँ। और इसे उदाहरण के लिए एक पथ पर सहेजें: "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 create TestService binpath = "C: \ Python36 \ Python.exe c: \ PythonFiles \ AppServerSvc.py" DisplayName = "TestService" start = auto

बिनपाथ का पहला तर्क python.exe का मार्ग है

द्विपथ का दूसरा तर्क आपकी अजगर फ़ाइल का पथ है जिसे हमने पहले ही बनाया था

याद न करें कि आपको हर " = " चिन्ह के बाद एक स्थान रखना चाहिए ।

फिर अगर सब कुछ ठीक है, तो आपको देखना चाहिए

[अनुसूचित जाति] क्रिएट सर्विस सफलता

अब आपकी अजगर सेवा को विंडोज़ सेवा के रूप में स्थापित किया गया है। आप इसे सेवा प्रबंधक और रजिस्ट्री में देख सकते हैं:

HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ TestService

3- अब ठीक है। आप सेवा प्रबंधक पर अपनी सेवा शुरू कर सकते हैं।

आप हर अजगर फ़ाइल को निष्पादित कर सकते हैं जो यह सेवा कंकाल प्रदान करता है।


वहाँ बहुत सारे बुरे उदाहरण हैं कि कैसे उपयोग करें SetEvent(self.hWaitStop)और WaitForSingleObject। शायद चयनित उत्तर की विचारहीन नकल के आधार पर। यह ऐसा करने का एक अच्छा तरीका है जो "डिबग" दोनों के लिए सफाई से काम करता है और "रोक" तर्कों को समाप्त करता है। (एससी का उपयोग करने के बारे में हिस्सा HandleCommandLineकाम करते समय बेमानी लगता है , और डिबग चला सकता है।)
अलियास_नाग

5

pysc: पायथन पर सेवा नियंत्रण प्रबंधक

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

3
क्या किसी को पता है कि यह एक चढ़ाव क्यों मिला? यह एक अच्छा समाधान की तरह लग रहा है।
जारोड चेसनी

4

अजगर में nssm 3+

(मैंने अपनी .py फ़ाइल को pyinstaller के साथ .exe में बदल दिया है )

nssm: जैसा कि पहले कहा गया था

  • nssm इंस्टॉल करें {ServiceName}
  • NSSM´s कंसोल पर:

    पथ: path \ to \ your \ program.exe

    Startup Directory : path \ to \ your \ #same पथ के रूप में, लेकिन आपके program.exe के बिना

    तर्क: खाली

यदि आप अपने प्रोजेक्ट को .exe में कनवर्ट नहीं करना चाहते हैं

  • के साथ .bat फ़ाइल बनाएँ python {{your python.py file name}}
  • और .bat फ़ाइल का पथ सेट करें

आभासी वातावरण कैसे प्रदान करें?
शीक मोईद

3

मैंने pywin32 के साथ एक सेवा के रूप में होस्ट करना शुरू किया ।

सब कुछ ठीक था लेकिन मैं इस समस्या से मिला कि सिस्टम स्टार्टअप पर 30 सेकंड (विंडोज के लिए डिफ़ॉल्ट टाइमआउट) के भीतर सेवा शुरू करने में सक्षम नहीं था। यह मेरे लिए महत्वपूर्ण था क्योंकि एक भौतिक मशीन पर होस्ट की गई कई वर्चुअल मशीनों पर विंडोज स्टार्टअप एक साथ होता था, और आईओ लोड बहुत बड़ा था। त्रुटि संदेश थे:

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.

मैंने पीविन के साथ बहुत संघर्ष किया, लेकिन एनएसएसएम का उपयोग करने के साथ समाप्त हो गया क्योंकि यह इस उत्तर में प्रस्तावित था । इसके लिए पलायन करना बहुत आसान था।


1

लूप या सबथ्रेड का उपयोग करके एक पूर्ण pywin32 उदाहरण

कुछ दिनों के लिए इस पर काम करने के बाद, यहाँ जवाब है कि मैं इसे अच्छा और आत्म निहित रखने के लिए pywin32 का उपयोग करके खोज करना चाहूंगा।

यह एक लूप-आधारित और एक थ्रेड-आधारित समाधान के लिए पूर्ण कार्य कोड है। यह अजगर 2 और 3 दोनों पर काम कर सकता है, हालांकि मैंने केवल 2.7 और Win7 पर नवीनतम संस्करण का परीक्षण किया है। मतदान कोड के लिए लूप अच्छा होना चाहिए, और ट्रेड को अधिक सर्वर जैसे कोड के साथ काम करना चाहिए। ऐसा लगता है कि वेट्रेस wsgi सर्वर के साथ अच्छी तरह से काम करता है जिसके पास शालीनतापूर्वक बंद करने का एक मानक तरीका नहीं है।

मैं यह भी नोट करना चाहूंगा कि वहाँ उदाहरणों का भार लगता है, इस तरह से यह लगभग उपयोगी है, लेकिन वास्तव में भ्रामक है, क्योंकि उन्होंने अन्य उदाहरणों को आँख बंद करके काट दिया है। मै गलत हो सकता हूँ। लेकिन अगर आप कभी इसके लिए इंतजार नहीं करते तो एक घटना क्यों बनाएं

उन्होंने कहा कि मुझे अभी भी लगता है कि मैं यहां कुछ अस्थिर जमीन पर हूं, विशेष रूप से इस संबंध में कि थ्रेड संस्करण से निकास कितना साफ है, लेकिन कम से कम मेरा मानना ​​है कि यहां कुछ भी भ्रामक नहीं है।

बस चलाने के लिए कोड को फ़ाइल में कॉपी करें और निर्देशों का पालन करें।

अपडेट करें:

धागे को समाप्त करने के लिए एक सरल ध्वज का उपयोग करें। महत्वपूर्ण बिट यह है कि "थ्रेड किया गया" प्रिंट।
एक uncooperative सर्वर थ्रेड से बाहर निकलने के लिए अधिक विस्तृत उदाहरण के लिए वेट्रेस 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
# with "start" and "stop" watch for files to appear
# check Windows EventViever for log messages

import socket
import sys
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():
    global do_run
    while do_run:
        dummytask_once(msg='loop')
        time.sleep(3)


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

    def run(self):
        global do_run
        do_run = True
        print('thread start\n')
        dummytask_loop()
        print('thread done\n')

    def exit(self):
        global do_run
        do_run = False


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('main start')
        self.server = MyThread()
        self.server.start()
        print('wait for win32event')
        win32event.WaitForSingleObject(self.stopEvt, win32event.INFINITE)
        self.server.exit()
        print('wait for thread')
        self.server.join()
        print('main 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()

0

win32serviceutilकार्यों का उपयोग करके स्वीकृत उत्तर लेकिन जटिल है और डीबगिंग और परिवर्तन को कठिन बनाता है। यह है अब तक NSSM (उपयोग में आसान गैर सकिंग सेवा प्रबंधक) । आप एक सामान्य अजगर कार्यक्रम को लिखते और आराम से डिबग करते हैं और जब यह अंततः काम करता है तो आप इसे एक मिनट से भी कम समय में सेवा के रूप में स्थापित करने के लिए एनएसएसएम का उपयोग करते हैं:

एक उन्नत (व्यवस्थापक) कमांड प्रॉम्प्ट से आप चलाते हैं nssm.exe install NameOfYourServiceऔर आप इन विकल्पों को भरते हैं:

  • पथ : (python.exe के लिए पथ उदा C:\Python27\Python.exe)
  • तर्क : (आपके अजगर लिपि का मार्ग, उदा c:\path\to\program.py)

वैसे, यदि आपका प्रोग्राम उन उपयोगी संदेशों को प्रिंट करता है, जिन्हें आप लॉग फ़ाइल में रखना चाहते हैं, तो एनएसएसएम भी इसे और आपके लिए बहुत कुछ संभाल सकता है।


हां, यह एड्रियानो के जवाब की नकल है। मैंने उस उत्तर को उकेरा और उसे संपादित करने की कोशिश की लेकिन संपादन के बाद मैं एक नए उत्तर को देख रहा था।
ndemou

आभासी वातावरण कैसे प्रदान करें?
शीक मोईद

0

यह उत्तर StackOverflow पर कई स्रोतों से साहित्यिक चोरी है - उनमें से अधिकांश ऊपर, लेकिन मैं दूसरों को भूल गया हूं - क्षमा करें। यह सरल है और स्क्रिप्ट "जैसा है" चलती है। रिलीज़ के लिए आप स्क्रिप्ट का परीक्षण करते हैं, फिर इसे सर्वर पर कॉपी करें और संबंधित सेवा को रोकें / प्रारंभ करें। और यह सभी स्क्रिप्टिंग भाषाओं (पायथन, पर्ल, नोड.जेएस), प्लस बैच स्क्रिप्ट जैसे कि GitBash, PowerShell, यहां तक ​​कि पुरानी DOS बैट स्क्रिप्ट के लिए काम करना चाहिए। pyGlue वह गोंद है जो विंडोज सर्विसेज और आपकी स्क्रिप्ट के बीच बैठता है।

'''
A script to create a Windows Service, which, when started, will run an executable with the specified parameters.
Optionally, you can also specify a startup directory

To use this script you MUST define (in class Service)
1. A name for your service (short - preferably no spaces)
2. A display name for your service (the name visibile in Windows Services)
3. A description for your service (long details visible when you inspect the service in Windows Services)
4. The full path of the executable (usually C:/Python38/python.exe or C:WINDOWS/System32/WindowsPowerShell/v1.0/powershell.exe
5. The script which Python or PowerShell will run(or specify None if your executable is standalone - in which case you don't need pyGlue)
6. The startup directory (or specify None)
7. Any parameters for your script (or for your executable if you have no script)

NOTE: This does not make a portable script.
The associated '_svc_name.exe' in the dist folder will only work if the executable,
(and any optional startup directory) actually exist in those locations on the target system

Usage: 'pyGlue.exe [options] install|update|remove|start [...]|stop|restart [...]|debug [...]'
Options for 'install' and 'update' commands only:
        --username domain\\username : The Username the service is to run under
        --password password : The password for the username
        --startup [manual|auto|disabled|delayed] : How the service starts, default = manual
        --interactive : Allow the service to interact with the desktop.
        --perfmonini file: .ini file to use for registering performance monitor data
        --perfmondll file: .dll file to use when querying the service for performance data, default = perfmondata.dll
Options for 'start' and 'stop' commands only:
        --wait seconds: Wait for the service to actually start or stop.
                If you specify --wait with the 'stop' option, the service and all dependent services will be stopped,
                each waiting the specified period.
'''

# Import all the modules that make life easy
import servicemanager
import socket
import sys
import win32event
import win32service
import win32serviceutil
import win32evtlogutil
import os
from logging import Formatter, Handler
import logging
import subprocess


# Define the win32api class
class Service (win32serviceutil.ServiceFramework):
        # The following variable are edited by the build.sh script
        _svc_name_ = "TestService"
        _svc_display_name_ = "Test Service"
        _svc_description_ = "Test Running Python Scripts as a Service"
        service_exe = 'c:/Python27/python.exe'
        service_script = None
        service_params = []
        service_startDir = None

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

        # Configure logging to the WINDOWS Event logs
        def configure_logging(self):
                self.formatter = Formatter('%(message)s')
                self.handler = logHandler()
                self.handler.setFormatter(self.formatter)
                self.logger = logging.getLogger()
                self.logger.addHandler(self.handler)
                self.logger.setLevel(logging.INFO)

        # Stop the service
        def SvcStop(self):
                self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
                win32event.SetEvent(self.hWaitStop)

        # Run the service
        def SvcDoRun(self):
                self.main()

        # This is the service
        def main(self):

                # Log that we are starting
                servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STARTED,
                                                          (self._svc_name_, ''))

                # Fire off the real process that does the real work
                logging.info('%s - about to call Popen() to run %s %s %s', self._svc_name_, self.service_exe, self.service_script, self.service_params)
                self.process = subprocess.Popen([self.service_exe, self.service_script] + self.service_params, shell=False, cwd=self.service_startDir)
                logging.info('%s - started process %d', self._svc_name_, self.process.pid)

                # Wait until WINDOWS kills us - retrigger the wait for stop every 60 seconds
                rc = None
                while rc != win32event.WAIT_OBJECT_0:
                        rc = win32event.WaitForSingleObject(self.hWaitStop, (1 * 60 * 1000))

                # Shut down the real process and exit
                logging.info('%s - is terminating process %d', self._svc_name_, self.process.pid)
                self.process.terminate()
                logging.info('%s - is exiting', self._svc_name_)


class logHandler(Handler):
        '''
Emit a log record to the WINDOWS Event log
        '''

        def emit(self, record):
                servicemanager.LogInfoMsg(record.getMessage())


# The main code
if __name__ == '__main__':
        '''
Create a Windows Service, which, when started, will run an executable with the specified parameters.
        '''

        # Check that configuration contains valid values just in case this service has accidentally
        # been moved to a server where things are in different places
        if not os.path.isfile(Service.service_exe):
                print('Executable file({!s}) does not exist'.format(Service.service_exe), file=sys.stderr)
                sys.exit(0)
        if not os.access(Service.service_exe, os.X_OK):
                print('Executable file({!s}) is not executable'.format(Service.service_exe), file=sys.stderr)
                sys.exit(0)
        # Check that any optional startup directory exists
        if (Service.service_startDir is not None) and (not os.path.isdir(Service.service_startDir)):
                print('Start up directory({!s}) does not exist'.format(Service.service_startDir), file=sys.stderr)
                sys.exit(0)

        if len(sys.argv) == 1:
                servicemanager.Initialize()
                servicemanager.PrepareToHostSingle(Service)
                servicemanager.StartServiceCtrlDispatcher()
        else:
                # install/update/remove/start/stop/restart or debug the service
                # One of those command line options must be specified
                win32serviceutil.HandleCommandLine(Service)

अब संपादन का एक सा है और आप 'pyGlue' नामक अपनी सभी सेवाओं को नहीं चाहते हैं। तो बिट्स में प्लग करने के लिए एक स्क्रिप्ट (build.sh) है और एक अनुकूलित 'pyGlue' और एक '.exe' बनाएं। यह यह '.exe' है जो विंडोज सर्विस के रूप में स्थापित हो जाता है। एक बार स्थापित होने के बाद आप इसे स्वचालित रूप से चलाने के लिए सेट कर सकते हैं।

#!/bin/sh
# This script build a Windows Service that will install/start/stop/remove a service that runs a script
# That is, executes Python to run a Python script, or PowerShell to run a PowerShell script, etc

if [ $# -lt 6 ]; then
        echo "Usage: build.sh Name Display Description Executable Script StartupDir [Params]..."
        exit 0
fi

name=$1
display=$2
desc=$3
exe=$4
script=$5
startDir=$6
shift; shift; shift; shift; shift; shift
params=
while [ $# -gt 0 ]; do
        if [ "${params}" != "" ]; then
                params="${params}, "
        fi
        params="${params}'$1'"
        shift
done

cat pyGlue.py | sed -e "s/pyGlue/${name}/g" | \
        sed -e "/_svc_name_ =/s?=.*?= '${name}'?" | \
        sed -e "/_svc_display_name_ =/s?=.*?= '${display}'?" | \
        sed -e "/_svc_description_ =/s?=.*?= '${desc}'?" | \
        sed -e "/service_exe =/s?=.*?= '$exe'?" | \
        sed -e "/service_script =/s?=.*?= '$script'?" | \
        sed -e "/service_params =/s?=.*?= [${params}]?" | \
        sed -e "/service_startDir =/s?=.*?= '${startDir}'?" > ${name}.py

cxfreeze ${name}.py --include-modules=win32timezone

स्थापना - निर्दिष्ट फ़ोल्डर में '.exe' सर्वर और स्क्रिप्ट की प्रतिलिपि बनाएँ। 'इंस्टाल' विकल्प के साथ प्रशासक के रूप में '.exe' चलाएं। व्यवस्थापक के रूप में, Windows सेवाएँ खोलें और आप सेवा शुरू करें। अपग्रेड के लिए, बस स्क्रिप्ट के नए संस्करण को कॉपी करें और सेवा को रोकें / शुरू करें।

अब हर सर्वर अलग है - पायथन की अलग-अलग स्थापना, अलग-अलग फ़ोल्डर संरचनाएँ। मैं pyGlue.py और build.sh की एक प्रति के साथ, हर सर्वर के लिए एक फ़ोल्डर बनाए रखता हूं। और मैं उस सर्वर पर सभी सेवा के पुनर्निर्माण के लिए एक 'serverBuild.sh' स्क्रिप्ट बनाता हूं।

# A script to build all the script based Services on this PC
sh build.sh AutoCode 'AutoCode Medical Documents' 'Autocode Medical Documents to SNOMED_CT and AIHW codes' C:/Python38/python.exe autocode.py C:/Users/russell/Documents/autocoding -S -T

-1

https://www.chrisumbel.com/article/windows_services_in_python

  1. PySvc.py का पालन करें

  2. dll फ़ोल्डर को बदल रहा है

मुझे पता है कि यह पुराना है लेकिन मैं इस पर हमेशा के लिए अटक गया। मेरे लिए, इस फ़ाइल को कॉपी करके इस विशिष्ट समस्या को हल किया गया था - pywintypes36.dll

से -> Python36 \ Lib \ साइट-संकुल \ pywin32_system32

के लिए -> Python36 \ Lib \ साइट-संकुल \ win32

setx /M PATH "%PATH%;C:\Users\user\AppData\Local\Programs\Python\Python38-32;C:\Users\user\AppData\Local\Programs\Python\Python38-32\Scripts;C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\pywin32_system32;C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\win32
  1. अजगर फ़ोल्डर में पथ बदलकर

cd C:\Users\user\AppData\Local\Programs\Python\Python38-32

  1. NET START PySvc
  2. NET STOP PySvc
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.