NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

win32.py (4235B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\cherrypy\process\win32.py
      2 import os
      3 import win32api
      4 import win32con
      5 import win32event
      6 import win32service
      7 import win32serviceutil
      8 from cherrypy.process import wspbus, plugins
      9 
     10 class ConsoleCtrlHandler(plugins.SimplePlugin):
     11 
     12     def __init__(self, bus):
     13         self.is_set = False
     14         plugins.SimplePlugin.__init__(self, bus)
     15 
     16     def start(self):
     17         if self.is_set:
     18             self.bus.log('Handler for console events already set.', level=40)
     19             return
     20         result = win32api.SetConsoleCtrlHandler(self.handle, 1)
     21         if result == 0:
     22             self.bus.log('Could not SetConsoleCtrlHandler (error %r)' % win32api.GetLastError(), level=40)
     23         else:
     24             self.bus.log('Set handler for console events.', level=40)
     25             self.is_set = True
     26 
     27     def stop(self):
     28         if not self.is_set:
     29             self.bus.log('Handler for console events already off.', level=40)
     30             return
     31         try:
     32             result = win32api.SetConsoleCtrlHandler(self.handle, 0)
     33         except ValueError:
     34             result = 1
     35 
     36         if result == 0:
     37             self.bus.log('Could not remove SetConsoleCtrlHandler (error %r)' % win32api.GetLastError(), level=40)
     38         else:
     39             self.bus.log('Removed handler for console events.', level=40)
     40             self.is_set = False
     41 
     42     def handle(self, event):
     43         if event in (win32con.CTRL_C_EVENT,
     44          win32con.CTRL_LOGOFF_EVENT,
     45          win32con.CTRL_BREAK_EVENT,
     46          win32con.CTRL_SHUTDOWN_EVENT,
     47          win32con.CTRL_CLOSE_EVENT):
     48             self.bus.log('Console event %s: shutting down bus' % event)
     49             try:
     50                 self.stop()
     51             except ValueError:
     52                 pass
     53 
     54             self.bus.exit()
     55             return 1
     56         return 0
     57 
     58 
     59 class Win32Bus(wspbus.Bus):
     60 
     61     def __init__(self):
     62         self.events = {}
     63         wspbus.Bus.__init__(self)
     64 
     65     def _get_state_event(self, state):
     66         try:
     67             return self.events[state]
     68         except KeyError:
     69             event = win32event.CreateEvent(None, 0, 0, 'WSPBus %s Event (pid=%r)' % (state.name, os.getpid()))
     70             self.events[state] = event
     71             return event
     72 
     73     def _get_state(self):
     74         return self._state
     75 
     76     def _set_state(self, value):
     77         self._state = value
     78         event = self._get_state_event(value)
     79         win32event.PulseEvent(event)
     80 
     81     state = property(_get_state, _set_state)
     82 
     83     def wait(self, state, interval = 0.1, channel = None):
     84         if isinstance(state, (tuple, list)):
     85             if self.state not in state:
     86                 events = tuple([ self._get_state_event(s) for s in state ])
     87                 win32event.WaitForMultipleObjects(events, 0, win32event.INFINITE)
     88         elif self.state != state:
     89             event = self._get_state_event(state)
     90             win32event.WaitForSingleObject(event, win32event.INFINITE)
     91 
     92 
     93 class _ControlCodes(dict):
     94 
     95     def key_for(self, obj):
     96         for key, val in self.items():
     97             if val is obj:
     98                 return key
     99 
    100         raise ValueError('The given object could not be found: %r' % obj)
    101 
    102 
    103 control_codes = _ControlCodes({'graceful': 138})
    104 
    105 def signal_child(service, command):
    106     if command == 'stop':
    107         win32serviceutil.StopService(service)
    108     elif command == 'restart':
    109         win32serviceutil.RestartService(service)
    110     else:
    111         win32serviceutil.ControlService(service, control_codes[command])
    112 
    113 
    114 class PyWebService(win32serviceutil.ServiceFramework):
    115     _svc_name_ = 'Python Web Service'
    116     _svc_display_name_ = 'Python Web Service'
    117     _svc_deps_ = None
    118     _exe_name_ = 'pywebsvc'
    119     _exe_args_ = None
    120     _svc_description_ = 'Python Web Service'
    121 
    122     def SvcDoRun(self):
    123         from cherrypy import process
    124         process.bus.start()
    125         process.bus.block()
    126 
    127     def SvcStop(self):
    128         from cherrypy import process
    129         self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
    130         process.bus.exit()
    131 
    132     def SvcOther(self, control):
    133         process.bus.publish(control_codes.key_for(control))
    134 
    135 
    136 if __name__ == '__main__':
    137     win32serviceutil.HandleCommandLine(PyWebService)