当 Windows 关闭时,我无法弄清楚为什么SvcShutdown()
我的 win32 服务没有被调用。其他一切都完美无缺(停止、暂停/继续等)。在网上搜索了几个小时后,我什么也没找到。
任何帮助将非常非常感谢!
提前致谢,
詹姆士
import win32serviceutil
import servicemanager
import win32service
import win32event
import win32api
import datetime
LOGINFO = 0
LOGWARNING = 1
LOGERROR = 2
class MyService(win32serviceutil.ServiceFramework):
_svc_name_ = 'MyService'
_svc_display_name_ = 'MyService service'
def __init__(self, *args):
win32serviceutil.ServiceFramework.__init__(self, *args)
# Create events for service stop, pause & continue
# CreateEvent(securityAttrs, bManualReset, bInitialState, name)
self.evStop = win32event.CreateEvent(None, 0, 0, None)
self.evPause = win32event.CreateEvent(None, 0, 0, None)
self.evContinue = win32event.CreateEvent(None, 0, 0, None)
# Create event list for WaitForMultipleObjects()
self.evhandles = self.evStop, self.evPause, self.evContinue
# sigStatus must be this range for a valid SCM event
self.validSignals = range(win32event.WAIT_OBJECT_0,
win32event.MAXIMUM_WAIT_OBJECTS)
# Signal ID returned from WFMO() else None
self.sigStatus = None
# Service run state. False means pausing/paused or stopping
self.runState = True
def logEvent(self, msg, logtype=LOGINFO, logcategory=None):
import servicemanager
if logtype == LOGINFO:
servicemanager.LogInfoMsg(str(msg))
elif logtype == LOGWARNING:
servicemanager.LogWarningMsg(str(msg))
elif logtype == LOGERROR:
servicemanager.LogErrorMsg(str(msg))
def sleep(self, sec):
'''A delay method sympathetic to SCM notifications.'''
while sec > 0:
# SCM event has taken place?
if self.notificationFromSCM():
break
win32api.Sleep(1000)
sec = sec -1
def notificationFromSCM(self):
'''Returns True if SCM notification(s) have taken place.
sigStatus has the value.
Note: that calls to WaitForMultipleObjects() only returns the event
status ONCE, after which it's reset (ie. calling it may return
WAIT_OBJECT_0 and an immediate subsequent call will yield WAIT_TIMEOUT
or similar.'''
if self.sigStatus is not None:
# Still have a live SCM event to process, so exit
return True
# WaitForMultipleObjects(handles, bWaitAll, dwMilliseconds)
self.sigStatus = win32event.WaitForMultipleObjects(self.evhandles, 0, 0)
if self.sigStatus in self.validSignals:
return True
else:
# Timeout signal or similar, so MUST reset sigStatus
self.sigStatus = None
return False
def SvcDoRun(self):
self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
self.logEvent('Starting {0} Service...'.format(self._svc_display_name_))
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
self.logEvent('{0} Service started.'.format(self._svc_display_name_))
while True:
if self.runState:
try:
# Insert service work activity here...
self.logEvent('Working: {0}'.format(datetime.datetime.now()))
self.sleep(10)
except Exception as x:
self.logEvent('Exception : {0}'.format(x), LOGERROR)
else:
self.sleep(30)
# SCM notification?
if self.notificationFromSCM():
if self.sigStatus == self.evhandles.index(self.evStop):
# STOP event
self.logEvent('Stopping {0} Service...'.format(self._svc_display_name_))
break
elif self.sigStatus == self.evhandles.index(self.evPause):
# PAUSE event
self.logEvent('Pausing {0} Service...'.format(self._svc_display_name_))
self.runState = False
# Other cleanup code here...
self.logEvent('{0} Service paused.'.format(self._svc_display_name_))
self.ReportServiceStatus(win32service.SERVICE_PAUSED)
elif self.sigStatus == self.evhandles.index(self.evContinue):
# CONTINUE event
self.logEvent('Resuming {0} service...'.format(self._svc_display_name_))
self.runState = True
# Reset pause & continue to non-signaled state
win32event.ResetEvent(self.evPause)
win32event.ResetEvent(self.evContinue)
# Other cleanup code here...
self.logEvent('{0} Service started.'.format(self._svc_display_name_))
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
# Clear signal flag
self.sigStatus = None
# If we get here, then service has been stopped/shutdown
self.logEvent('{0} Service stopped.'.format(self._svc_display_name_))
self.ReportServiceStatus(win32service.SERVICE_STOPPED)
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
# Signal STOP event
win32event.SetEvent(self.evStop)
def SvcPause(self):
self.ReportServiceStatus(win32service.SERVICE_PAUSE_PENDING)
# Signal PAUSE event
win32event.SetEvent(self.evPause)
def SvcContinue(self):
self.ReportServiceStatus(win32service.SERVICE_CONTINUE_PENDING)
# Signal CONTINUE event
win32event.SetEvent(self.evContinue)
def SvcShutdown(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
self.logEvent('**SvcShutdown event**')
# Shutdown code here...
win32event.SetEvent(self.evStop)