56 """Serves microscope devices via a Windows service.
58 Win32 service manipulation relies on fetching _svc_name_ without
59 instantiating any object, so _svc_name_ must be a class
60 attribute. This means that only one MicroscopeService may be
61 installed on any one system, and will be responsible for serving
62 all microscope devices on that system.
65 _svc_name_ =
"MicroscopeService"
66 _svc_display_name_ =
"Microscope device servers"
67 _svc_description_ =
"Serves microscope devices."
70 def set_config_file(cls, path):
71 win32serviceutil.SetServiceCustomOption(
72 cls.
_svc_name_,
"config", os.path.abspath(path)
76 def get_config_file(cls):
77 return win32serviceutil.GetServiceCustomOption(
81 def log(self, message, error=False):
83 logFunc = servicemanager.LogErrorMsg
85 logFunc = servicemanager.LogInfoMsg
88 def __init__(self, args):
90 win32serviceutil.ServiceFramework.__init__(self, args)
94 configfile = win32serviceutil.GetServiceCustomOption(
97 os.chdir(os.path.dirname(configfile))
98 self.
log(
"Using config file %s." % configfile)
99 self.
log(
"Logging at %s." % os.getcwd())
100 self.ReportServiceStatus(win32service.SERVICE_RUNNING)
108 options = DeviceServerOptions(
109 config_fpath=configfile,
110 logging_level=logging.INFO,
114 devices = validate_devices(configfile)
115 serve_devices(devices, options, self.
stop_event)
116 except Exception
as e:
117 servicemanager.LogErrorMsg(str(e))
120 self.
log(
"Service shutdown complete.")
121 self.ReportServiceStatus(win32service.SERVICE_STOPPED)
124 self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)