home *** CD-ROM | disk | FTP | other *** search
Wrap
# Source Generated with Decompyle++ # File: in.pyo (Python 2.7) import win32service import win32api import win32con import winerror import sys import pywintypes import os error = RuntimeError def LocatePythonServiceExe(exeName = None): if not exeName and hasattr(sys, 'frozen'): return sys.executable if None is None: if os.path.splitext(win32service.__file__)[0].endswith('_d'): exeName = 'PythonService_d.exe' else: exeName = 'PythonService.exe' if os.path.isfile(exeName): return win32api.GetFullPathName(exeName) baseName = None.path.splitext(os.path.basename(exeName))[0] try: exeName = win32api.RegQueryValue(win32con.HKEY_LOCAL_MACHINE, 'Software\\Python\\%s\\%s' % (baseName, sys.winver)) if os.path.isfile(exeName): return exeName raise None("The executable '%s' is registered as the Python service exe, but it does not exist as specified" % exeName) except win32api.error: for path in [ sys.prefix] + sys.path: look = os.path.join(path, exeName) if os.path.isfile(look): return win32api.GetFullPathName(look) try: return win32api.SearchPath(None, exeName)[0] except win32api.error: msg = '%s is not correctly registered\nPlease locate and run %s, and it will self-register\nThen run this service registration process again.' % (exeName, exeName) raise error(msg) def _GetServiceShortName(longName): access = win32con.KEY_READ | win32con.KEY_ENUMERATE_SUB_KEYS | win32con.KEY_QUERY_VALUE hkey = win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE, 'SYSTEM\\CurrentControlSet\\Services', 0, access) num = win32api.RegQueryInfoKey(hkey)[0] longName = longName.lower() for x in range(0, num): svc = win32api.RegEnumKey(hkey, x) skey = win32api.RegOpenKey(hkey, svc, 0, access) try: thisName = str(win32api.RegQueryValueEx(skey, 'DisplayName')[0]) if thisName.lower() == longName: return svc continue except win32api.error: continue return None def SmartOpenService(hscm, name, access): try: return win32service.OpenService(hscm, name, access) except win32api.error: details = None if details.winerror not in [ winerror.ERROR_SERVICE_DOES_NOT_EXIST, winerror.ERROR_INVALID_NAME]: raise name = win32service.GetServiceKeyName(hscm, name) return win32service.OpenService(hscm, name, access) def LocateSpecificServiceExe(serviceName): hkey = win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE, 'SYSTEM\\CurrentControlSet\\Services\\%s' % serviceName, 0, win32con.KEY_ALL_ACCESS) try: return win32api.RegQueryValueEx(hkey, 'ImagePath')[0] finally: hkey.Close() def InstallPerfmonForService(serviceName, iniName, dllName = None): if not dllName: dllName = win32api.GetProfileVal('Python', 'dll', '', iniName) if not dllName: try: tryName = os.path.join(os.path.split(win32service.__file__)[0], 'perfmondata.dll') if os.path.isfile(tryName): dllName = tryName except AttributeError: pass if not dllName: raise ValueError('The name of the performance DLL must be available') dllName = win32api.GetFullPathName(dllName) hkey = win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE, 'SYSTEM\\CurrentControlSet\\Services\\%s' % serviceName, 0, win32con.KEY_ALL_ACCESS) try: subKey = win32api.RegCreateKey(hkey, 'Performance') try: win32api.RegSetValueEx(subKey, 'Library', 0, win32con.REG_SZ, dllName) win32api.RegSetValueEx(subKey, 'Open', 0, win32con.REG_SZ, 'OpenPerformanceData') win32api.RegSetValueEx(subKey, 'Close', 0, win32con.REG_SZ, 'ClosePerformanceData') win32api.RegSetValueEx(subKey, 'Collect', 0, win32con.REG_SZ, 'CollectPerformanceData') finally: win32api.RegCloseKey(subKey) finally: win32api.RegCloseKey(hkey) try: import perfmon (path, fname) = os.path.split(iniName) oldPath = os.getcwd() if path: os.chdir(path) try: perfmon.LoadPerfCounterTextStrings('python.exe ' + fname) finally: os.chdir(oldPath) except win32api.error: details = None print 'The service was installed OK, but the performance monitor' print 'data could not be loaded.', details def _GetCommandLine(exeName, exeArgs): if exeArgs is not None: return exeName + ' ' + exeArgs return None def InstallService(pythonClassString, serviceName, displayName, startType = None, errorControl = None, bRunInteractive = 0, serviceDeps = None, userName = None, password = None, exeName = None, perfMonIni = None, perfMonDll = None, exeArgs = None, description = None): if startType is None: startType = win32service.SERVICE_DEMAND_START serviceType = win32service.SERVICE_WIN32_OWN_PROCESS if bRunInteractive: serviceType = serviceType | win32service.SERVICE_INTERACTIVE_PROCESS if errorControl is None: errorControl = win32service.SERVICE_ERROR_NORMAL exeName = '"%s"' % LocatePythonServiceExe(exeName) commandLine = _GetCommandLine(exeName, exeArgs) hscm = win32service.OpenSCManager(None, None, win32service.SC_MANAGER_ALL_ACCESS) try: hs = win32service.CreateService(hscm, serviceName, displayName, win32service.SERVICE_ALL_ACCESS, serviceType, startType, errorControl, commandLine, None, 0, serviceDeps, userName, password) if description is not None: try: win32service.ChangeServiceConfig2(hs, win32service.SERVICE_CONFIG_DESCRIPTION, description) except NotImplementedError: pass win32service.CloseServiceHandle(hs) finally: win32service.CloseServiceHandle(hscm) InstallPythonClassString(pythonClassString, serviceName) if perfMonIni is not None: InstallPerfmonForService(serviceName, perfMonIni, perfMonDll) def ChangeServiceConfig(pythonClassString, serviceName, startType = None, errorControl = None, bRunInteractive = 0, serviceDeps = None, userName = None, password = None, exeName = None, displayName = None, perfMonIni = None, perfMonDll = None, exeArgs = None, description = None): try: import perfmon perfmon.UnloadPerfCounterTextStrings('python.exe ' + serviceName) except (ImportError, win32api.error): pass exeName = '"%s"' % LocatePythonServiceExe(exeName) if startType is None: startType = win32service.SERVICE_NO_CHANGE if errorControl is None: errorControl = win32service.SERVICE_NO_CHANGE hscm = win32service.OpenSCManager(None, None, win32service.SC_MANAGER_ALL_ACCESS) serviceType = win32service.SERVICE_WIN32_OWN_PROCESS if bRunInteractive: serviceType = serviceType | win32service.SERVICE_INTERACTIVE_PROCESS commandLine = _GetCommandLine(exeName, exeArgs) try: hs = SmartOpenService(hscm, serviceName, win32service.SERVICE_ALL_ACCESS) try: win32service.ChangeServiceConfig(hs, serviceType, startType, errorControl, commandLine, None, 0, serviceDeps, userName, password, displayName) if description is not None: try: win32service.ChangeServiceConfig2(hs, win32service.SERVICE_CONFIG_DESCRIPTION, description) except NotImplementedError: pass finally: win32service.CloseServiceHandle(hs) finally: win32service.CloseServiceHandle(hscm) InstallPythonClassString(pythonClassString, serviceName) if perfMonIni is not None: InstallPerfmonForService(serviceName, perfMonIni, perfMonDll) def InstallPythonClassString(pythonClassString, serviceName): if pythonClassString: key = win32api.RegCreateKey(win32con.HKEY_LOCAL_MACHINE, 'System\\CurrentControlSet\\Services\\%s\\PythonClass' % serviceName) try: win32api.RegSetValue(key, None, win32con.REG_SZ, pythonClassString) finally: win32api.RegCloseKey(key) def SetServiceCustomOption(serviceName, option, value): try: serviceName = serviceName._svc_name_ except AttributeError: pass key = win32api.RegCreateKey(win32con.HKEY_LOCAL_MACHINE, 'System\\CurrentControlSet\\Services\\%s\\Parameters' % serviceName) try: if type(value) == type(0): win32api.RegSetValueEx(key, option, 0, win32con.REG_DWORD, value) else: win32api.RegSetValueEx(key, option, 0, win32con.REG_SZ, value) finally: win32api.RegCloseKey(key) def GetServiceCustomOption(serviceName, option, defaultValue = None): try: serviceName = serviceName._svc_name_ except AttributeError: pass key = win32api.RegCreateKey(win32con.HKEY_LOCAL_MACHINE, 'System\\CurrentControlSet\\Services\\%s\\Parameters' % serviceName) try: return win32api.RegQueryValueEx(key, option)[0] except win32api.error: return defaultValue finally: win32api.RegCloseKey(key) def RemoveService(serviceName): try: import perfmon perfmon.UnloadPerfCounterTextStrings('python.exe ' + serviceName) except (ImportError, win32api.error): pass hscm = win32service.OpenSCManager(None, None, win32service.SC_MANAGER_ALL_ACCESS) try: hs = SmartOpenService(hscm, serviceName, win32service.SERVICE_ALL_ACCESS) win32service.DeleteService(hs) win32service.CloseServiceHandle(hs) finally: win32service.CloseServiceHandle(hscm) import win32evtlogutil try: win32evtlogutil.RemoveSourceFromRegistry(serviceName) except win32api.error: pass def ControlService(serviceName, code, machine = None): hscm = win32service.OpenSCManager(machine, None, win32service.SC_MANAGER_ALL_ACCESS) try: hs = SmartOpenService(hscm, serviceName, win32service.SERVICE_ALL_ACCESS) try: status = win32service.ControlService(hs, code) finally: win32service.CloseServiceHandle(hs) finally: win32service.CloseServiceHandle(hscm) return status def __FindSvcDeps(findName): if type(findName) is pywintypes.UnicodeType: findName = str(findName) dict = { } k = win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE, 'SYSTEM\\CurrentControlSet\\Services') num = 0 while None: try: svc = win32api.RegEnumKey(k, num) except win32api.error: break num = num + 1 sk = win32api.RegOpenKey(k, svc) try: (deps, typ) = win32api.RegQueryValueEx(sk, 'DependOnService') except win32api.error: deps = () for dep in deps: dep = dep.lower() dep_on = dict.get(dep, []) dep_on.append(svc) dict[dep] = dep_on continue return __ResolveDeps(findName, dict) def __ResolveDeps(findName, dict): items = dict.get(findName.lower(), []) retList = [] for svc in items: retList.insert(0, svc) retList = __ResolveDeps(svc, dict) + retList return retList def WaitForServiceStatus(serviceName, status, waitSecs, machine = None): for i in range(waitSecs * 4): now_status = QueryServiceStatus(serviceName, machine)[1] if now_status == status: break win32api.Sleep(250) else: raise pywintypes.error(winerror.ERROR_SERVICE_REQUEST_TIMEOUT, 'QueryServiceStatus', win32api.FormatMessage(winerror.ERROR_SERVICE_REQUEST_TIMEOUT)[:-2]) def __StopServiceWithTimeout(hs, waitSecs = 30): try: status = win32service.ControlService(hs, win32service.SERVICE_CONTROL_STOP) except pywintypes.error: exc = None if exc.winerror != winerror.ERROR_SERVICE_NOT_ACTIVE: raise for i in range(waitSecs): status = win32service.QueryServiceStatus(hs) if status[1] == win32service.SERVICE_STOPPED: break win32api.Sleep(1000) else: raise pywintypes.error(winerror.ERROR_SERVICE_REQUEST_TIMEOUT, 'ControlService', win32api.FormatMessage(winerror.ERROR_SERVICE_REQUEST_TIMEOUT)[:-2]) def StopServiceWithDeps(serviceName, machine = None, waitSecs = 30): hscm = win32service.OpenSCManager(machine, None, win32service.SC_MANAGER_ALL_ACCESS) try: deps = __FindSvcDeps(serviceName) for dep in deps: hs = win32service.OpenService(hscm, dep, win32service.SERVICE_ALL_ACCESS) try: __StopServiceWithTimeout(hs, waitSecs) finally: win32service.CloseServiceHandle(hs) hs = win32service.OpenService(hscm, serviceName, win32service.SERVICE_ALL_ACCESS) try: __StopServiceWithTimeout(hs, waitSecs) finally: win32service.CloseServiceHandle(hs) finally: win32service.CloseServiceHandle(hscm) def StopService(serviceName, machine = None): return ControlService(serviceName, win32service.SERVICE_CONTROL_STOP, machine) def StartService(serviceName, args = None, machine = None): hscm = win32service.OpenSCManager(machine, None, win32service.SC_MANAGER_ALL_ACCESS) try: hs = SmartOpenService(hscm, serviceName, win32service.SERVICE_ALL_ACCESS) try: win32service.StartService(hs, args) finally: win32service.CloseServiceHandle(hs) finally: win32service.CloseServiceHandle(hscm) def RestartService(serviceName, args = None, waitSeconds = 30, machine = None): try: StopService(serviceName, machine) except pywintypes.error: exc = None if exc.winerror != winerror.ERROR_SERVICE_NOT_ACTIVE: raise for i in range(waitSeconds): try: StartService(serviceName, args, machine) continue except pywintypes.error: exc = None if exc.winerror != winerror.ERROR_SERVICE_ALREADY_RUNNING: raise win32api.Sleep(1000) continue else: print 'Gave up waiting for the old service to stop!' def _DebugCtrlHandler(evt): if evt in (win32con.CTRL_C_EVENT, win32con.CTRL_BREAK_EVENT): print 'Stopping debug service.' g_debugService.SvcStop() return True def DebugService(cls, argv = []): global g_debugService, g_debugService import servicemanager print 'Debugging service %s - press Ctrl+C to stop.' % (cls._svc_name_,) servicemanager.Debugging(True) servicemanager.PrepareToHostSingle(cls) g_debugService = cls(argv) win32api.SetConsoleCtrlHandler(_DebugCtrlHandler, True) try: g_debugService.SvcRun() finally: win32api.SetConsoleCtrlHandler(_DebugCtrlHandler, False) servicemanager.Debugging(False) g_debugService = None def GetServiceClassString(cls, argv = None): if argv is None: argv = sys.argv import pickle modName = pickle.whichmodule(cls, cls.__name__) if modName == '__main__': try: fname = win32api.GetFullPathName(argv[0]) path = os.path.split(fname)[0] fname = os.path.join(path, win32api.FindFiles(fname)[0][8]) except win32api.error: raise error("Could not resolve the path name '%s' to a full path" % argv[0]) modName = os.path.splitext(fname)[0] return modName + '.' + cls.__name__ def QueryServiceStatus(serviceName, machine = None): hscm = win32service.OpenSCManager(machine, None, win32service.SC_MANAGER_CONNECT) try: hs = SmartOpenService(hscm, serviceName, win32service.SERVICE_QUERY_STATUS) try: status = win32service.QueryServiceStatus(hs) finally: win32service.CloseServiceHandle(hs) finally: win32service.CloseServiceHandle(hscm) return status def usage(): try: fname = os.path.split(sys.argv[0])[1] except: fname = sys.argv[0] print "Usage: '%s [options] install|update|remove|start [...]|stop|restart [...]|debug [...]'" % fname print "Options for 'install' and 'update' commands only:" print ' --username domain\\username : The Username the service is to run under' print ' --password password : The password for the username' print ' --startup [manual|auto|disabled] : How the service starts, default = manual' print ' --interactive : Allow the service to interact with the desktop.' print ' --perfmonini file: .ini file to use for registering performance monitor data' print ' --perfmondll file: .dll file to use when querying the service for' print ' performance data, default = perfmondata.dll' print "Options for 'start' and 'stop' commands only:" print ' --wait seconds: Wait for the service to actually start or stop.' print " If you specify --wait with the 'stop' option, the service" print ' and all dependent services will be stopped, each waiting' print ' the specified period.' sys.exit(1) def HandleCommandLine(cls, serviceClassString = None, argv = None, customInstallOptions = '', customOptionHandler = None): err = 0 if argv is None: argv = sys.argv if len(argv) <= 1: usage() serviceName = cls._svc_name_ serviceDisplayName = cls._svc_display_name_ if serviceClassString is None: serviceClassString = GetServiceClassString(cls) import getopt try: (opts, args) = getopt.getopt(argv[1:], customInstallOptions, [ 'password=', 'username=', 'startup=', 'perfmonini=', 'perfmondll=', 'interactive', 'wait=']) except getopt.error: details = None print details usage() userName = None password = None perfMonIni = None perfMonDll = None startup = None interactive = None waitSecs = 0 for opt, val in opts: if opt == '--username': userName = val continue if opt == '--password': password = val continue if opt == '--perfmonini': perfMonIni = val continue if opt == '--perfmondll': perfMonDll = val continue if opt == '--interactive': interactive = 1 continue if opt == '--startup': map = { 'manual': win32service.SERVICE_DEMAND_START, 'auto': win32service.SERVICE_AUTO_START, 'disabled': win32service.SERVICE_DISABLED } try: startup = map[val.lower()] except KeyError: print "'%s' is not a valid startup option" % val if opt == '--wait': try: waitSecs = int(val) except ValueError: print '--wait must specify an integer number of seconds.' usage() arg = args[0] knownArg = 0 if arg == 'start': knownArg = 1 print 'Starting service %s' % serviceName try: StartService(serviceName, args[1:]) if waitSecs: WaitForServiceStatus(serviceName, win32service.SERVICE_RUNNING, waitSecs) except win32service.error: exc = None print 'Error starting service: %s' % exc.strerror err = exc.winerror if arg == 'restart': knownArg = 1 print 'Restarting service %s' % serviceName RestartService(serviceName, args[1:]) if waitSecs: WaitForServiceStatus(serviceName, win32service.SERVICE_RUNNING, waitSecs) elif arg == 'debug': knownArg = 1 if not hasattr(sys, 'frozen'): svcArgs = ' '.join(args[1:]) try: exeName = LocateSpecificServiceExe(serviceName) except win32api.error: exc = None if exc[0] == winerror.ERROR_FILE_NOT_FOUND: print 'The service does not appear to be installed.' print 'Please install the service before debugging it.' sys.exit(1) raise try: os.system('%s -debug %s %s' % (exeName, serviceName, svcArgs)) except KeyboardInterrupt: pass DebugService(cls, args) if not knownArg and len(args) != 1: usage() if arg == 'install': knownArg = 1 try: serviceDeps = cls._svc_deps_ except AttributeError: serviceDeps = None try: exeName = cls._exe_name_ except AttributeError: exeName = None try: exeArgs = cls._exe_args_ except AttributeError: exeArgs = None try: description = cls._svc_description_ except AttributeError: description = None print 'Installing service %s' % (serviceName,) try: InstallService(serviceClassString, serviceName, serviceDisplayName, serviceDeps = serviceDeps, startType = startup, bRunInteractive = interactive, userName = userName, password = password, exeName = exeName, perfMonIni = perfMonIni, perfMonDll = perfMonDll, exeArgs = exeArgs, description = description) if customOptionHandler: customOptionHandler(*(opts,)) print 'Service installed' except win32service.error: exc = None if exc.winerror == winerror.ERROR_SERVICE_EXISTS: arg = 'update' else: print 'Error installing service: %s (%d)' % (exc.strerror, exc.winerror) err = exc.winerror except ValueError: msg = None print 'Error installing service: %s' % str(msg) err = -1 try: RemoveService(serviceName) except win32api.error: print 'Warning - could not remove the partially installed service.' if arg == 'update': knownArg = 1 try: serviceDeps = cls._svc_deps_ except AttributeError: serviceDeps = None try: exeName = cls._exe_name_ except AttributeError: exeName = None try: exeArgs = cls._exe_args_ except AttributeError: exeArgs = None try: description = cls._svc_description_ except AttributeError: description = None print 'Changing service configuration' try: ChangeServiceConfig(serviceClassString, serviceName, serviceDeps = serviceDeps, startType = startup, bRunInteractive = interactive, userName = userName, password = password, exeName = exeName, displayName = serviceDisplayName, perfMonIni = perfMonIni, perfMonDll = perfMonDll, exeArgs = exeArgs, description = description) if customOptionHandler: customOptionHandler(*(opts,)) print 'Service updated' except win32service.error: exc = None print 'Error changing service configuration: %s (%d)' % (exc.strerror, exc.winerror) err = exc.winerror if arg == 'remove': knownArg = 1 print 'Removing service %s' % serviceName try: RemoveService(serviceName) print 'Service removed' except win32service.error: exc = None print 'Error removing service: %s (%d)' % (exc.strerror, exc.winerror) err = exc.winerror if arg == 'stop': knownArg = 1 print 'Stopping service %s' % serviceName try: if waitSecs: StopServiceWithDeps(serviceName, waitSecs = waitSecs) else: StopService(serviceName) except win32service.error: exc = None print 'Error stopping service: %s (%d)' % (exc.strerror, exc.winerror) err = exc.winerror if not knownArg: err = -1 print "Unknown command - '%s'" % arg usage() return err class ServiceFramework: _svc_deps_ = None _exe_name_ = None _exe_args_ = None _svc_description_ = None def __init__(self, args): import servicemanager self.ssh = servicemanager.RegisterServiceCtrlHandler(args[0], self.ServiceCtrlHandlerEx, True) servicemanager.SetEventSourceName(self._svc_name_) self.checkPoint = 0 def GetAcceptedControls(self): accepted = 0 if hasattr(self, 'SvcStop'): accepted = accepted | win32service.SERVICE_ACCEPT_STOP if hasattr(self, 'SvcPause') and hasattr(self, 'SvcContinue'): accepted = accepted | win32service.SERVICE_ACCEPT_PAUSE_CONTINUE if hasattr(self, 'SvcShutdown'): accepted = accepted | win32service.SERVICE_ACCEPT_SHUTDOWN return accepted def ReportServiceStatus(self, serviceStatus, waitHint = 5000, win32ExitCode = 0, svcExitCode = 0): if self.ssh is None: return None if None == win32service.SERVICE_START_PENDING: accepted = 0 else: accepted = self.GetAcceptedControls() if serviceStatus in [ win32service.SERVICE_RUNNING, win32service.SERVICE_STOPPED]: checkPoint = 0 else: self.checkPoint = self.checkPoint + 1 checkPoint = self.checkPoint status = (win32service.SERVICE_WIN32_OWN_PROCESS, serviceStatus, accepted, win32ExitCode, svcExitCode, checkPoint, waitHint) win32service.SetServiceStatus(self.ssh, status) def SvcInterrogate(self): self.ReportServiceStatus(win32service.SERVICE_RUNNING) def SvcOther(self, control): try: print 'Unknown control status - %d' % control except IOError: pass def ServiceCtrlHandler(self, control): self.ServiceCtrlHandlerEx(control, 0, None) def SvcOtherEx(self, control, event_type, data): self.SvcOther(control) def ServiceCtrlHandlerEx(self, control, event_type, data): if control == win32service.SERVICE_CONTROL_STOP: self.SvcStop() elif control == win32service.SERVICE_CONTROL_PAUSE: self.SvcPause() elif control == win32service.SERVICE_CONTROL_CONTINUE: self.SvcContinue() elif control == win32service.SERVICE_CONTROL_INTERROGATE: self.SvcInterrogate() elif control == win32service.SERVICE_CONTROL_SHUTDOWN: self.SvcShutdown() else: self.SvcOtherEx(control, event_type, data) def SvcRun(self): self.ReportServiceStatus(win32service.SERVICE_RUNNING) self.SvcDoRun() self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)