/usr/share/pyshared/Pyro/ext/BasicNTService.py is in pyro 1:3.14-1.2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 | #############################################################################
#
# An NT service that runs the Pyro Name Server
# Author: Syver Enstad; syver-en@online.no
# Bugfix for recent win32 builds: David Rushby; woodsplitter@rocketmail.com
#
# This is part of "Pyro" - Python Remote Objects
# Which is (c) Irmen de Jong - irmen@razorvine.net
#
#############################################################################
import sys
import win32serviceutil
import threading
import win32service
import win32api
import win32con
class BasicNTService(win32serviceutil.ServiceFramework, object):
""" Abstract base to help out with building NT services
in Python with the win32all(by Mark Hammond) support for
python nt services.
Remember to set the two following class attributes
to something sensible in your subclass
_svc_name_ = 'PyroNS'
_svc_display_name_ = 'Pyro Naming Service NT service'
The following are optional
_svc_deps_: This should be set to the list of service names
That need to be started before this one.
_exe_name_: This should be set to a service .EXE if you're not
going to use PythonService.exe
_svc_description_ : This is the descriptive string that you find
in the services applet
To register the service with the SCM the easiest way is to include the
following at the bottom of the file where your subclass is defined.
if __name__ == '__main__':
TheClassYouDerivedFromBasicNTService.HandleCommandLine()
"""
def __init__(self, args):
_redirectSystemStreamsIfNecessary()
win32serviceutil.ServiceFramework.__init__(self, args)
self._stopEvent = threading.Event()
def SvcStop(self):
""" Template method from win32serviceutil.ServiceFramework"""
# first tell SCM that we have started the stopping process
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
self._stopEvent.set()
def _shouldStop(self):
return self._stopEvent.isSet()
def _doRun(self):
raise NotImplementedError
def _doStop(self):
raise NotImplementedError
def SvcDoRun(self):
""" part of Template method SvcRun
from win32serviceutil.ServiceFramework"""
self.logStarted()
self._doRun()
self._stopEvent.wait()
self._doStop()
self.logTermination()
return 0
def logTermination(self):
import servicemanager
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STOPPED,
(self._svc_name_, ""))
def logStarted(self):
import servicemanager
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, ''))
def CustomOptionHandler(cls, opts):
#out=open("c:\\log.txt","w")
print "Installing the Pyro %s" % cls._svc_name_
args = raw_input("Enter command line arguments for %s: " % cls._svc_name_)
try:
createRegistryParameters(cls._svc_name_, args.strip())
except Exception,x:
print "Error occured when setting command line args in the registry: ",x
try:
cls._svc_description_
except LookupError:
return
key = win32api.RegCreateKey(win32con.HKEY_LOCAL_MACHINE,
"System\\CurrentControlSet\\Services\\%s" % cls._svc_name_)
try:
win32api.RegSetValueEx(key, "Description", 0, win32con.REG_SZ, cls._svc_description_);
finally:
win32api.RegCloseKey(key)
CustomOptionHandler = classmethod(CustomOptionHandler)
def HandleCommandLine(cls):
if win32serviceutil.HandleCommandLine(cls, customOptionHandler=cls.CustomOptionHandler) != 0:
return # some error occured
if sys.argv[1] in ("install", "update"):
print "\nYou can configure the command line arguments in the Registry."
print "The key is: HKLM\\System\\CurrentControlSet\\Services\\%s" % cls._svc_name_
print "The value under that key is: ", pyroArgsRegkeyName
args=getRegistryParameters(cls._svc_name_)
if args:
print "(it is currently set to: '%s')" % args
else:
print "(it is currently not set)"
print
HandleCommandLine = classmethod(HandleCommandLine)
pyroArgsRegkeyName = "PyroServiceArguments"
def getRegistryParameters(servicename):
key=win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\"+servicename)
try:
try:
(commandLine, regtype) = win32api.RegQueryValueEx(key,pyroArgsRegkeyName)
return commandLine
except:
pass
finally:
key.Close()
createRegistryParameters(servicename, pyroArgsRegkeyName)
return ""
def createRegistryParameters(servicename, parameters):
newkey=win32api.RegOpenKeyEx(win32con.HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\"+servicename,0,win32con.KEY_ALL_ACCESS)
try:
win32api.RegSetValueEx(newkey, pyroArgsRegkeyName, 0, win32con.REG_SZ, parameters)
finally:
newkey.Close()
def _redirectSystemStreamsIfNecessary():
# 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:
sys.stdout = sys.stderr = open('nul', 'w')
return shouldRedirect
|