คุณจะเรียกใช้สคริปต์ Python เป็นบริการใน Windows ได้อย่างไร


260

ฉันร่างสถาปัตยกรรมสำหรับชุดของโปรแกรมที่ใช้วัตถุที่สัมพันธ์กันต่าง ๆ ที่เก็บไว้ในฐานข้อมูล ฉันต้องการให้หนึ่งในโปรแกรมทำหน้าที่เป็นบริการที่ให้อินเทอร์เฟซระดับสูงกว่าสำหรับการดำเนินการกับวัตถุเหล่านี้และโปรแกรมอื่น ๆ เพื่อเข้าถึงวัตถุผ่านบริการนั้น

ขณะนี้ฉันกำลังตั้งเป้าสำหรับ Python และ Django framework เป็นเทคโนโลยีในการใช้บริการดังกล่าวด้วย ฉันค่อนข้างแน่ใจว่าฉันคิดวิธีการ daemonize โปรแกรม Python ใน Linux อย่างไรก็ตามมันเป็นรายการจำเพาะที่เป็นตัวเลือกที่ระบบควรรองรับ Windows ฉันมีประสบการณ์น้อยในการเขียนโปรแกรม Windows และไม่มีประสบการณ์เลยกับบริการของ Windows

เป็นไปได้ไหมที่จะเรียกใช้โปรแกรม Python ในฐานะบริการ Windows (เช่นทำงานโดยอัตโนมัติโดยไม่ต้องลงชื่อเข้าใช้ของผู้ใช้)ฉันไม่จำเป็นต้องดำเนินการในส่วนนี้ แต่ฉันต้องการความคิดคร่าวๆว่าจะทำอย่างไรเพื่อตัดสินใจว่าจะออกแบบตามแนวเหล่านี้หรือไม่

แก้ไข: ขอบคุณสำหรับคำตอบทั้งหมดจนถึงตอนนี้พวกเขาค่อนข้างครอบคลุม ฉันต้องการทราบอีกสิ่งหนึ่ง: Windows ทราบถึงบริการของฉันอย่างไร ฉันสามารถจัดการมันด้วยยูทิลิตี้ Windows ดั้งเดิมได้หรือไม่ อะไรคือสิ่งที่เทียบเท่ากับการใส่สคริปต์เริ่ม / หยุดใน /etc/init.d?


2
ตรวจสอบเรื่องนี้แม่แบบบริการของ Windowsจะใช้win32service API
CMS

คำตอบ:


254

ใช่คุณสามารถ. ฉันใช้ไลบรารี 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วิธีการ


21
หลังจากเขียนโค้ดฉันจะบอกให้ Windows เรียกใช้บริการนี้ได้อย่างไร
ชุด

33
@Kit: เรียกใช้สคริปต์ของคุณด้วยจากบรรทัดคำสั่งด้วยพารามิเตอร์ "ติดตั้ง" จากนั้นคุณจะสามารถเห็นแอปพลิเคชันของคุณในรายการบริการของ Windows ที่ซึ่งคุณสามารถเริ่มทำงานได้หยุดทำงานหรือตั้งค่าให้เริ่มโดยอัตโนมัติ
Ricardo Reyes

16
คุณกล่าวถึงเป็นพิเศษกับ pythoncom และคุณนำเข้ามันในรหัสตัวอย่างของคุณ ปัญหาคือคุณไม่เคยใช้ pythoncom ที่ใดก็ได้ในโค้ดตัวอย่างของคุณคุณนำเข้าเท่านั้น ทำไมถึงพูดถึงพิเศษแล้วไม่แสดงการใช้งาน?
Buttons840

10
ทำไมถึงsocket.setdefaulttimeout(60)เป็น? มันจำเป็นสำหรับการบริการหรือเป็นเพียงแค่คัดลอกโดยไม่ตั้งใจจากบริการที่มีอยู่บางส่วน? :)
Timur

7
chrisumbel.com/article/windows_services_in_python อันนี้เป็นตัวอย่างที่คล้ายกัน แต่สมบูรณ์กว่า
csprabala

41

แม้ว่าฉันจะตอบคำถามที่เลือกไว้สองสามสัปดาห์ก่อน แต่ในระหว่างนี้ฉันก็พยายามดิ้นรนมากขึ้นในหัวข้อนี้ รู้สึกเหมือนมีการติดตั้ง Python แบบพิเศษและใช้โมดูลพิเศษเพื่อเรียกใช้สคริปต์เนื่องจากบริการนั้นเป็นวิธีที่ผิด แล้วความสะดวกในการพกพาล่ะ?

ฉันสะดุดกับผู้จัดการบริการไม่ดูดซึ่งทำให้มันง่ายและมีสติในการจัดการกับบริการ Windows ฉันคิดว่าฉันสามารถส่งตัวเลือกไปยังบริการที่ติดตั้งได้ฉันก็เลือก Python ที่ทำงานได้ของฉันและส่งสคริปต์เป็นตัวเลือก

ฉันยังไม่ได้ลองวิธีนี้ แต่ฉันจะทำตอนนี้และอัปเดตโพสต์นี้ตลอดกระบวนการ ฉันสนใจที่จะใช้ virtualenvs บน Windows ดังนั้นฉันอาจจะมาพร้อมกับการสอนไม่ช้าก็เร็วและเชื่อมโยงกับที่นี่


มีโชคหรือเปล่า? ฉันกำลังสร้างเว็บไซต์ที่ง่ายมากสำหรับลูกค้าและไม่จำเป็นต้องใช้กอง Apache ทั้งหมด อีกทั้งการสร้างบริการด้วยตัวเองก็ฟังดูเหมือนเป็นการเชื้อเชิญสำหรับปัญหาเช่นกันเพราะฉันได้อ่านจากความคิดเห็นอื่น
Jaran

ใช่มันใช้งานได้ง่ายมาก คุณเพียงแค่ให้เส้นทางและข้อโต้แย้งสำหรับสคริปต์ ฉันสามารถทำให้ฉันทำงานโดยไม่ต้องใช้คอนโซลในกรณีที่บางคนจบลงด้วยหน้าต่างคอนโซลอย่างใด
kmcguire

ขณะนี้เห็นได้ชัดว่าทำงานได้มีปัญหาอื่น ๆ โดยเฉพาะอย่างยิ่งเมื่อคุณ "ไม่จำเป็นต้องใช้ Apache stack ทั้งหมด": ตัวอย่างเช่น gunicorn ยังไม่ทำงานบน Windows ซึ่งจริงๆแล้วเป็น showstopper สำหรับฉัน
mknaf

4
เคล็ดลับที่นี่คือการเรียกใช้ python.exe เป็นบริการและสคริปต์ python ของคุณเป็นพารามิเตอร์: เช่น "nssm ติดตั้ง MyServiceName c: \ python27 \ python.exe c: \ temp \ myscript.py"
poleguy

ใช้งานได้ดี! บนระบบที่มีสภาพแวดล้อมเสมือนหลายพา ธ สามารถอ้างอิง Python interpreter exe ในไดเรกทอรี Scripts ของสภาพแวดล้อมเสมือนที่ต้องการ ดูเหมือนว่าnew-serviceใน PowerShell ควรจะสามารถทำได้ แต่เริ่มต้น (และตรวจสอบ) สคริปต์เป็นบริการที่เกี่ยวข้องกับรายละเอียดชัดเจนมากซึ่ง nssm ดูแลอย่างดี
Fred Schleifer

26

วิธีที่ง่ายที่สุดคือใช้: NSSM - ตัวจัดการบริการที่ไม่ได้ดูด:

1 - ทำการดาวน์โหลดบนhttps://nssm.cc/download

2 - ติดตั้งโปรแกรมหลามเป็นบริการ: ชนะพรอมต์ในฐานะผู้ดูแล

c:> nssm.exe ติดตั้ง WinService

3 - บนคอนโซล NSSM:

พา ธ : C: \ Python27 \ Python27.exe

ไดเรกทอรีเริ่มต้น: C: \ Python27

อาร์กิวเมนต์: c: \ WinService.py

4 - ตรวจสอบบริการที่สร้างบน services.msc


ฉันเคยใช้ nssm.exe ติดตั้ง Visual Studio C ++ .exe เป็นบริการและตอนนี้ฉันสามารถใช้ nssm.exe ได้เช่นกันสำหรับ Python .pyc ของฉันเป็นบริการ ขอบคุณ
etoricky

หมายเหตุ: หากสคริปต์ * .py ของคุณอยู่ในโฟลเดอร์ที่มีช่องว่าง (เช่น: C: \ Program Files \ myapp.py) ต้องระบุอาร์กิวเมนต์ในเครื่องหมายคำพูด: อาร์กิวเมนต์: "C: \ Program Files \ myapp.py"
Yury Kozlov

วิธีการจัดให้มีสภาพแวดล้อมเสมือนจริง?
Shaik moeed

24

วิธีที่ง่ายที่สุดในการบรรลุเป้าหมายนี้คือการใช้ native command 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

แอพของฉันทำงานได้ดีนอกบริการและฉันใช้รหัสเดียวกันด้านบนโดยไม่มีผลลัพธ์
nimeresam

วิธีการจัดให้มีสภาพแวดล้อมเสมือนจริง?
Shaik moeed

คุณลอง virtualenv หรือไม่
pyOwner

1
มันใช้งานไม่ได้ บริการ Windows จะต้องเปิดเผยอินเทอร์เฟซบางอย่างที่แพ็คเกจ pywin32 ทำ อย่างไรก็ตามสคริปต์ Python แบบเก่าจะไม่เพียงพอ
Siddhartha Gandhi

23

มีสองทางเลือกในการติดตั้งเป็นบริการที่สามารถใช้งานกับ Windows ได้

วิธีที่ 1: ใช้ instsrv และ srvany จาก rktools.exe

สำหรับ Windows Home Server หรือ Windows Server 2003 (ทำงานร่วมกับ WinXP เกินไป) ที่ใช้ Windows Server 2003 ทรัพยากร Kit เครื่องมือมาพร้อมกับระบบสาธารณูปโภคที่สามารถนำมาใช้ควบคู่นี้เรียกว่าinstsrv.exeและsrvany.exe ดูบทความ KB ของ Microsoft นี้KB137890สำหรับรายละเอียดเกี่ยวกับวิธีใช้อุปกรณ์เหล่านี้

สำหรับ Windows Home Server มี wrapper ที่เป็นมิตรกับผู้ใช้ที่ยอดเยี่ยมสำหรับยูทิลิตี้เหล่านี้ชื่อ aptly " Any Service Installer "

วิธีที่ 2: ใช้ ServiceInstaller สำหรับ Windows NT

มีอีกทางเลือกหนึ่งคือการใช้ServiceInstaller สำหรับ Windows NT ( ดาวน์โหลดสามารถที่นี่ ) กับคำแนะนำหลามใช้ได้ ตรงกันข้ามกับชื่อมันใช้งานได้กับทั้ง Windows 2000 และ Windows XP เช่นกัน ต่อไปนี้เป็นคำแนะนำเกี่ยวกับวิธีการติดตั้งสคริปต์ python เป็นบริการ

การติดตั้งสคริปต์ Python

เรียกใช้ 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

หลังจากติดตั้งแล้วให้เปิดแอปเพล็ตบริการของแผงควบคุมเลือกและเริ่มบริการ PythonTest

หลังจากคำตอบแรกของฉันฉันสังเกตเห็นว่ามีคำถามและคำตอบที่เกี่ยวข้องอย่างใกล้ชิดได้โพสต์ไว้ใน SO ดูสิ่งนี้ด้วย:

ฉันสามารถเรียกใช้สคริปต์ Python เป็นบริการ (ใน Windows) ได้หรือไม่ อย่างไร?

ฉันจะทำให้ Windows รับรู้ถึงบริการที่ฉันเขียนด้วย Python ได้อย่างไร


ผมเพิ่งสังเกตเห็นมีอื่น ๆ ที่คล้ายกัน Q & A แล้ว: stackoverflow.com/questions/32404/... stackoverflow.com/questions/34328/...
popcnt

Service Installer ไม่ทำงานบนสถาปัตยกรรม 64 บิตดังนั้นตัวเลือก 1 จะกลายเป็นตัวเลือก goto
โนอาห์แคมป์เบล

ลิงก์ด้านบนไปยัง ServiceInstaller ไม่ทำงานอีกต่อไป ฉันพบที่นี่: sites.google.com/site/conort/…
LarsH

2
ปิดทราบฉันไม่คิดว่าNTจะจำเป็นต้อง "ตรงกันข้าม" กับชื่ออย่างน้อยไม่ได้อยู่ในคำพูดของโปรแกรมเมอร์ชาวบ้าน มันหมายถึง " สถาปัตยกรรม NT " ซึ่งตรงข้ามกับ "NT brand " ที่กล่าวว่าตามการพูดคุยเกี่ยวกับวิกิพีเดียนี้ขึ้นอยู่กับการอภิปรายตั้งแต่ "มันไม่ได้เป็นคำไมโครซอฟท์อย่างเป็นทางการ" แต่ยังคงมีประเพณีกับแนวความคิดนี้
n611x007

15

คำอธิบายทีละขั้นตอนวิธีทำให้มันใช้งานได้:

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 สร้าง TestService binpath = "C: \ Python36 \ Python.exe c: \ PythonFiles \ AppServerSvc.py" DisplayName = "TestService" start = auto

อาร์กิวเมนต์แรกของbinpathคือเส้นทางของ python.exe

อาร์กิวเมนต์ที่สองของbinpath คือเส้นทางของไฟล์ไพ ธ อนที่เราสร้างไว้แล้ว

อย่าพลาดว่าคุณควรใส่ช่องว่างหลังเครื่องหมาย " = " ทุกช่อง

ถ้าทุกอย่างโอเคคุณควรเห็น

[SC] CreateService SUCCESS

ตอนนี้บริการหลามของคุณได้รับการติดตั้งเป็นบริการ windows ทันที คุณสามารถดูได้ในตัวจัดการบริการและรีจิสทรีภายใต้:

HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ TestService

3- ตกลงตอนนี้ คุณสามารถเริ่มบริการของคุณได้ที่ผู้จัดการบริการ

คุณสามารถดำเนินการทุกไฟล์หลามที่ให้โครงกระดูกบริการนี้


ยังมีอีกหลายตัวอย่างที่ไม่ดีออกมีวิธีการที่จะใช้และSetEvent(self.hWaitStop) WaitForSingleObjectจากการคัดลอกคำตอบที่เลือกอย่างไม่คิดนี่อาจ นี่เป็นวิธีที่ดีในการทำงานอย่างสมบูรณ์สำหรับทั้ง "debug" สิ้นสุดอาร์กิวเมนต์ "stop" (ส่วนที่เกี่ยวกับการใช้ SC ดูเหมือนซ้ำซ้อนเมื่อHandleCommandLineทำงานและสามารถเรียกใช้ดีบักได้)
Alias_Knagg

3

pysc: Service Control Manager บน Python

ตัวอย่างสคริปต์เพื่อเรียกใช้เป็นบริการที่นำมาจาก 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
ไม่มีใครรู้ว่าทำไมสิ่งนี้จึงมีการลงคะแนนเสียง ดูเหมือนว่าเป็นทางออกที่ดี
Jarrod Chesney

3

ฉันเริ่มโฮสต์เป็นบริการด้วยpywin32 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 ตามที่เสนอในคำตอบนี้ มันง่ายมากที่จะโยกย้ายไป


2

nssmใน python 3+

(ฉันแปลงไฟล์. py ของฉันเป็น. exe ด้วยpyinstaller )

nssm: อย่างที่พูดไว้ก่อนหน้านี้

  • เรียกใช้การติดตั้ง nssm {ServiceName}
  • บนคอนโซล NSSM:

    เส้นทาง: เส้นทาง \ to \ your \ program.exe

    ไดเรกทอรีเริ่มต้น: เส้นทาง \ to \ your \ #same เป็นเส้นทาง แต่ไม่มี program.exe ของคุณ

    อาร์กิวเมนต์: ว่างเปล่า

หากคุณไม่ต้องการแปลงโครงการเป็น. exe

  • สร้างไฟล์. bat ด้วย python {{your python.py file name}}
  • และกำหนดเส้นทางไปยังไฟล์. bat

วิธีการจัดให้มีสภาพแวดล้อมเสมือนจริง?
Shaik moeed

1

ตัวอย่าง pywin32 ที่สมบูรณ์โดยใช้ลูปหรือเธรดย่อย

หลังจากทำงานในและนอกเวลาสองสามวันนี่คือคำตอบที่ฉันอยากจะพบโดยใช้ pywin32 เพื่อให้มันดีและอยู่ในตัวเอง

นี่คือรหัสการทำงานที่สมบูรณ์สำหรับโซลูชันแบบวนซ้ำและแบบอิงเธรดหนึ่งรายการ มันอาจทำงานได้ทั้ง python 2 และ 3 แม้ว่าฉันจะทดสอบเฉพาะรุ่นล่าสุดที่ 2.7 และ Win7 เท่านั้น การวนซ้ำควรเป็นสิ่งที่ดีสำหรับรหัสการลงคะแนนและดอกยางควรทำงานกับรหัสที่คล้ายกับเซิร์ฟเวอร์มากขึ้น ดูเหมือนว่าจะทำงานได้ดีกับเซิร์ฟเวอร์ wsgi พนักงานเสิร์ฟที่ไม่มีวิธีมาตรฐานในการปิดระบบได้อย่างสวยงาม

ฉันยังต้องการที่จะทราบว่ามีตัวอย่างมากมายที่นั่นเช่น นี้ซึ่งมีประโยชน์เกือบ แต่ในความเป็นจริงทำให้เข้าใจผิดเพราะพวกเขาได้ตัดและวางตัวอย่างอื่น ๆ อย่างสุ่มสี่สุ่มห้า ฉันอาจจะผิด แต่ทำไมต้องสร้างกิจกรรมหากคุณไม่เคยรอเลย

ที่กล่าวว่าฉันยังคงรู้สึกว่าฉันอยู่บนพื้นค่อนข้างสั่นคลอนที่นี่โดยเฉพาะอย่างยิ่งเกี่ยวกับความสะอาดทางออกจากรุ่นด้ายเป็น แต่อย่างน้อยฉันเชื่อว่าไม่มีอะไร ทำให้เข้าใจผิดที่นี่

ในการรันเพียงคัดลอกรหัสไปยังไฟล์และทำตามคำแนะนำ

อัปเดต:

ใช้การตั้งค่าสถานะง่าย ๆ เพื่อยกเลิกเธรด บิตที่สำคัญคือ "เธรดเสร็จ" พิมพ์
สำหรับตัวอย่างที่ซับซ้อนมากขึ้นออกจากเซิร์ฟเวอร์ด้ายความร่วมมือของฉันดูโพสต์เกี่ยวกับเซิร์ฟเวอร์พนักงานเสิร์ฟ 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 เพื่อติดตั้งเป็นบริการในเวลาไม่ถึงนาที:

จากคำสั่งการยกระดับ (ผู้ดูแลระบบ) ให้คุณเรียกใช้nssm.exe install NameOfYourServiceและคุณกรอกตัวเลือกเหล่านี้:

  • เส้นทาง : (เส้นทางไปยัง python.exe เช่นC:\Python27\Python.exe)
  • อาร์กิวเมนต์ : (พา ธ ไปยังสคริปต์ของคุณเช่นc:\path\to\program.py)

อย่างไรก็ตามถ้าโปรแกรมของคุณพิมพ์ข้อความที่มีประโยชน์ที่คุณต้องการเก็บไว้ในล็อกไฟล์ NSSM สามารถจัดการสิ่งนี้และอื่น ๆ อีกมากมายให้คุณ


ใช่นี่เป็นคำตอบที่ซ้ำกันของ Adriano ฉัน upvoted คำตอบนั้นและพยายามแก้ไข แต่หลังจากการแก้ไขฉันกำลังดูคำตอบใหม่
ndemou

วิธีการให้สภาพแวดล้อมเสมือนจริง?
Shaik moeed

0

สำหรับผู้ที่ต้องการสร้างบริการใน VENV หรือ Pycharm !!!!!!!

หลังจากอ่าน anwsers ทั้งหมดและสร้างสคริปต์บางอย่างถ้าคุณสามารถเรียกใช้python service.py installและpython service.py debugแต่python service.py startไม่มีการตอบสนอง

บางทีมันอาจจะเกิดจากปัญหา venv เพราะบริการ windows เริ่มบริการของคุณโดย PROJECT\venv\Lib\site-packages\win32\pythonservice.exeexec

คุณสามารถใช้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)

ถ้าคุณได้รับข้อผิดพลาดบางอย่างผมแล้วคุณสามารถตรวจสอบคำตอบของฉันในคำถามอื่นผมคงมันและโพสต์รหัสของฉันที่นี่


-1

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

  1. ติดตาม PySvc.py

  2. เปลี่ยนโฟลเดอร์ dll

ฉันรู้ว่านี่เก่า แต่ฉันติดอยู่กับเรื่องนี้ตลอดไป สำหรับฉันปัญหานี้แก้ไขโดยการคัดลอกไฟล์นี้ - pywintypes36.dll

จาก -> Python36 \ Lib \ site-packages \ pywin32_system32

ถึง -> Python36 \ Lib \ site-packages \ 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. เปลี่ยนเส้นทางไปยังโฟลเดอร์ python โดย

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

  1. NET START PySvc
  2. NET STOP PySvc
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.