BioImager  3.9.1
A .NET microscopy imaging library. Supports various microscopes by using imported libraries & GUI automation. Supported libraries include PriorĀ® & ZeissĀ® & all devices supported by Micromanager 2.0 and python-microscope.
Loading...
Searching...
No Matches
win32.py
1#!/usr/bin/env python3
2
3## Copyright (C) 2020 Mick Phillips <mick.phillips@gmail.com>
4##
5## This file is part of Microscope.
6##
7## Microscope is free software: you can redistribute it and/or modify
8## it under the terms of the GNU General Public License as published by
9## the Free Software Foundation, either version 3 of the License, or
10## (at your option) any later version.
11##
12## Microscope is distributed in the hope that it will be useful,
13## but WITHOUT ANY WARRANTY; without even the implied warranty of
14## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15## GNU General Public License for more details.
16##
17## You should have received a copy of the GNU General Public License
18## along with Microscope. If not, see <http://www.gnu.org/licenses/>.
19
20"""Win32 specific microscope classes.
21
22If called as a program, it will configure and control a Windows
23service to serve devices, similar to the device-server program.
24
25To configure and run as a Windows service use::
26
27 python -m microscope.win32 \
28 [install,remove,update,start,stop,restart,status] \
29 CONFIG-FILE
30
31"""
32
33
34import logging
35import multiprocessing
36import os
37import sys
38
39import servicemanager
40
41
42# These win32* modules both import win32api which is a pyd file.
43# Importing win32api can be problematic because of Windows things
44# specially when running as a Windows. So if it fails, add the
45# executable path to the DLL search PATH.
46try:
47 import win32service
48 import win32serviceutil
49except:
50 os.environ["PATH"] += ";" + os.path.split(sys.executable)[0]
51 import win32service
52 import win32serviceutil
53
54
55class MicroscopeWindowsService(win32serviceutil.ServiceFramework):
56 """Serves microscope devices via a Windows service.
57
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.
63 """
64
65 _svc_name_ = "MicroscopeService"
66 _svc_display_name_ = "Microscope device servers"
67 _svc_description_ = "Serves microscope devices."
68
69 @classmethod
70 def set_config_file(cls, path):
71 win32serviceutil.SetServiceCustomOption(
72 cls._svc_name_, "config", os.path.abspath(path)
73 )
74
75 @classmethod
76 def get_config_file(cls):
77 return win32serviceutil.GetServiceCustomOption(
78 cls._svc_name_, "config"
79 )
80
81 def log(self, message, error=False):
82 if error:
83 logFunc = servicemanager.LogErrorMsg
84 else:
85 logFunc = servicemanager.LogInfoMsg
86 logFunc("%s: %s" % (self._svc_name_, message))
87
88 def __init__(self, args):
89 # Initialise service framework.
90 win32serviceutil.ServiceFramework.__init__(self, args)
91 self.stop_event = multiprocessing.Event()
92
93 def SvcDoRun(self):
94 configfile = win32serviceutil.GetServiceCustomOption(
95 self._svc_name_, "config"
96 )
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)
101
102 from microscope.device_server import (
103 serve_devices,
104 validate_devices,
105 DeviceServerOptions,
106 )
107
108 options = DeviceServerOptions(
109 config_fpath=configfile,
110 logging_level=logging.INFO,
111 )
112
113 try:
114 devices = validate_devices(configfile)
115 serve_devices(devices, options, self.stop_event)
116 except Exception as e:
117 servicemanager.LogErrorMsg(str(e))
118 # Exit with non-zero error code so Windows will attempt to restart.
119 sys.exit(-1)
120 self.log("Service shutdown complete.")
121 self.ReportServiceStatus(win32service.SERVICE_STOPPED)
122
123 def SvcStop(self):
124 self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
125 self.stop_event.set()
126
127
128def handle_command_line():
129 if len(sys.argv) == 1:
130 print("\nNo action specified.\n", file=sys.stderr)
131 sys.exit(1)
132 if sys.argv[1].lower() in ["install", "update"]:
133 if len(sys.argv) == 2:
134 print("\nNo config file specified.\n")
135 sys.exit(1)
136 configfile = sys.argv.pop()
137 win32serviceutil.HandleCommandLine(MicroscopeWindowsService)
138 # Set persistent data on service
139 MicroscopeWindowsService.set_config_file(configfile)
140 else:
141 win32serviceutil.HandleCommandLine(MicroscopeWindowsService)
142
143
144if __name__ == "__main__":
145 handle_command_line()
def log(self, message, error=False)
Definition: win32.py:81