def __init__(self, args): super().__init__(args) # Create an event which we will use to wait on. The "service stop" # request will set this event. # * We must make it inheritable so we can pass it to the child # process via the cmd-line # * Must be manual reset so each child process and our service # all get woken from a single set of the event. sa = win32security.SECURITY_ATTRIBUTES() sa.bInheritHandle = True self.hWaitStop = win32event.CreateEvent(sa, True, False, None) self.args = args self.dirs = None self.runner_prefix = None # Patch up the service messages file in a frozen exe. # (We use the py2exe option that magically bundles the .pyd files # into the .zip file - so servicemanager.pyd doesn't exist.) if is_frozen and servicemanager.RunningAsService(): msg_file = os.path.join(os.path.dirname(sys.executable), "buildbot.msg") if os.path.isfile(msg_file): servicemanager.Initialize("BuildBot", msg_file) else: self.warning("Strange - '%s' does not exist" % (msg_file, ))
def redirectSystemStreamsIfNecessary(stdout=None, stderr=None): # Python programs running as Windows NT services must not send output to # the default sys.stdout or sys.stderr streams, because those streams are # not fully functional in the NT service execution environment. Sending # output to them will eventually (but not immediately) cause an IOError # ("Bad file descriptor"), which can be quite mystifying to the # uninitiated. This problem can be overcome by replacing the default # system streams with a stream that discards any data passed to it (like # redirection to /dev/null on Unix). # # However, the pywin32 service framework supports a debug mode, under which # the streams are fully functional and should not be redirected. shouldRedirect = True try: import servicemanager except ImportError: # If we can't even 'import servicemanager', we're obviously not running # as a service, so the streams shouldn't be redirected. shouldRedirect = False else: # Unlike previous builds, pywin32 builds >= 200 allow the # servicemanager module to be imported even in a program that isn't # running as a service. In such a situation, it would not be desirable # to redirect the system streams. # # However, it was not until pywin32 build 203 that a 'RunningAsService' # predicate was added to allow client code to determine whether it's # running as a service. # # This program logic redirects only when necessary if using any build # of pywin32 except 200-202. With 200-202, the redirection is a bit # more conservative than is strictly necessary. if servicemanager.Debugging() or \ (hasattr(servicemanager, 'RunningAsService') and not servicemanager.RunningAsService()): shouldRedirect = False if shouldRedirect: if not stdout: stdout = open('nul', 'w') sys.stdout = stdout if not stderr: stderr = open('nul', 'w') sys.stderr = stderr return shouldRedirect
def main(cmd, base_path, home_conf, winhndl=None): if base_path not in sys.path: sys.path.insert(0, base_path) Path.force_set_umit_conf(home_conf) log = file_log(Path.sched_log) globals()['log'] = log # Trying to adjust signals when running as a windows service won't work # since it needs to be adjusted while on the main thread. if not servicemanager.RunningAsService(): if os.name == "posix": signal.signal(signal.SIGHUP, safe_shutdown) signal.signal(signal.SIGTERM, safe_shutdown) signal.signal(signal.SIGINT, safe_shutdown) cmds = {'start': start} cmds[cmd](winhndl=winhndl)
log.info("Resuming emadb %s Windows service", __version__) logger.sysLogInfo("Resuming emadb %s Windows service" % __version__) win32event.SetEvent(self.resume) def SvcOtherEx(self, control, event_type, data): '''Implements a Reload functionality as a service custom control''' if control == SERVICE_CONTROL_RELOAD: self.SvcDoReload() else: self.SvcOther(control) def SvcDoReload(self): logger.sysLogInfo("reloading emadb service") win32event.SetEvent(self.reload) def SvcDoRun(self): '''Service Run entry point''' logger.sysLogInfo("Starting emadb %s Windows service" % __version__) self.server.run() self.server.stop() logger.sysLogInfo("emadb %s Windows service stopped" % __version__) def ctrlHandler(ctrlType): return True if not servicemanager.RunningAsService(): win32api.SetConsoleCtrlHandler(ctrlHandler, True) win32serviceutil.HandleCommandLine(WindowsService)