2012-11-03 39 views
1

我不知道爲什麼SvcShutdown()沒有在我的win32服務Windows被關閉時調用。其他一切正常工作(停止,暫停/繼續等)。在網上搜索了幾個小時之後,我什麼都沒發現。爲什麼不是由我的服務調用SvcShutdown()?

任何幫助將非常,非常感謝!

由於提前,

詹姆斯

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) 

回答

0
+0

@Remy [從建議的編輯感動] - 欣賞的反饋。不與ctrl處理程序相關的實際原因 - 服務與SCM協同工作並向SCM提供一個ctrl處理程序。實際發生的事情是,在該服務關閉之前,eventlog服務正在關閉,因此關閉時的事件未被記錄。 'SvcShutdown()'實際上被調用,但是這個消息沒有被記錄。 - 詹姆士 – Mormegil

相關問題