Döngü veya alt iplik kullanan eksiksiz bir pywin32 örneği
Birkaç gün boyunca bu açık ve kapalı çalıştıktan sonra, burada bulmak isterdim, pywin32'yi güzel ve kendine yeten tutmak için kullanarak cevap.
Bu, bir döngü tabanlı ve bir iş parçacığı tabanlı çözüm için tam çalışma kodudur. Python 2 ve 3 üzerinde çalışabilir, ancak en son sürümü 2.7 ve Win7'de test ettim. Döngü, yoklama kodu için iyi olmalı ve basamak daha sunucu benzeri bir kodla çalışmalıdır. Zarifce kapatmak için standart bir yolu olmayan garson wsgi sunucusu ile güzel görünüyor .
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. ama hiç beklemiyorsan neden bir etkinlik yaratıyorsun?
Bu, özellikle iplik sürümünden çıkışın ne kadar temiz olduğu konusunda, burada biraz titrek bir zeminde olduğumu hala hissediyorum, ama en azından burada yanıltıcı bir şey olmadığına inanıyorum .
Çalıştırmak için kodu bir dosyaya kopyalayın ve talimatları izleyin.
Güncelleme:
İş parçacığını sonlandırmak için basit bir bayrak kullanın. Önemli olan, "iş parçacığı bitti" yazdırmasıdır. İşbirlikçi olmayan
bir sunucu iş parçacığından çıkan daha ayrıntılı bir örnek için, garson wsgi sunucusu hakkındaki yazımı gö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
# 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()