루프 또는 서브 스레드를 사용하는 완전한 pywin32 예제
며칠 동안이 작업을 수행 한 후 여기에 pywin32를 사용하여 멋지고 독립적으로 유지하려는 답이 있습니다.
이것은 하나의 루프 기반 및 하나의 스레드 기반 솔루션에 대한 완전한 작업 코드입니다. 2.7 및 Win7의 최신 버전 만 테스트했지만 파이썬 2와 3 모두에서 작동 할 수 있습니다. 루프는 폴링 코드에 적합해야하며 트레드는 서버와 유사한 코드로 작동해야합니다. 정상적으로 종료하는 표준 방법이없는 웨이트리스 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()