Commit 45618ef3 authored by 's avatar

Rearranged the order of some imports - the prior version happened to

work if you had an existing 1.5.2 installation, but would fail on a
machine dependent solely on Zope's built-in python.
parent 1f2f786b
############################################################################## ##############################################################################
# #
# Zope Public License (ZPL) Version 1.0 # Zope Public License (ZPL) Version 1.0
# ------------------------------------- # -------------------------------------
# #
# Copyright (c) Digital Creations. All rights reserved. # Copyright (c) Digital Creations. All rights reserved.
# #
# This license has been certified as Open Source(tm). # This license has been certified as Open Source(tm).
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are # modification, are permitted provided that the following conditions are
# met: # met:
# #
# 1. Redistributions in source code must retain the above copyright # 1. Redistributions in source code must retain the above copyright
# notice, this list of conditions, and the following disclaimer. # notice, this list of conditions, and the following disclaimer.
# #
# 2. Redistributions in binary form must reproduce the above copyright # 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in # notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the # the documentation and/or other materials provided with the
# distribution. # distribution.
# #
# 3. Digital Creations requests that attribution be given to Zope # 3. Digital Creations requests that attribution be given to Zope
# in any manner possible. Zope includes a "Powered by Zope" # in any manner possible. Zope includes a "Powered by Zope"
# button that is installed by default. While it is not a license # button that is installed by default. While it is not a license
# violation to remove this button, it is requested that the # violation to remove this button, it is requested that the
# attribution remain. A significant investment has been put # attribution remain. A significant investment has been put
# into Zope, and this effort will continue if the Zope community # into Zope, and this effort will continue if the Zope community
# continues to grow. This is one way to assure that growth. # continues to grow. This is one way to assure that growth.
# #
# 4. All advertising materials and documentation mentioning # 4. All advertising materials and documentation mentioning
# features derived from or use of this software must display # features derived from or use of this software must display
# the following acknowledgement: # the following acknowledgement:
# #
# "This product includes software developed by Digital Creations # "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment # for use in the Z Object Publishing Environment
# (http://www.zope.org/)." # (http://www.zope.org/)."
# #
# In the event that the product being advertised includes an # In the event that the product being advertised includes an
# intact Zope distribution (with copyright and license included) # intact Zope distribution (with copyright and license included)
# then this clause is waived. # then this clause is waived.
# #
# 5. Names associated with Zope or Digital Creations must not be used to # 5. Names associated with Zope or Digital Creations must not be used to
# endorse or promote products derived from this software without # endorse or promote products derived from this software without
# prior written permission from Digital Creations. # prior written permission from Digital Creations.
# #
# 6. Modified redistributions of any form whatsoever must retain # 6. Modified redistributions of any form whatsoever must retain
# the following acknowledgment: # the following acknowledgment:
# #
# "This product includes software developed by Digital Creations # "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment # for use in the Z Object Publishing Environment
# (http://www.zope.org/)." # (http://www.zope.org/)."
# #
# Intact (re-)distributions of any official Zope release do not # Intact (re-)distributions of any official Zope release do not
# require an external acknowledgement. # require an external acknowledgement.
# #
# 7. Modifications are encouraged but must be packaged separately as # 7. Modifications are encouraged but must be packaged separately as
# patches to official Zope releases. Distributions that do not # patches to official Zope releases. Distributions that do not
# clearly separate the patches from the original work must be clearly # clearly separate the patches from the original work must be clearly
# labeled as unofficial distributions. Modifications which do not # labeled as unofficial distributions. Modifications which do not
# carry the name Zope may be packaged in any form, as long as they # carry the name Zope may be packaged in any form, as long as they
# conform to all of the clauses above. # conform to all of the clauses above.
# #
# #
# Disclaimer # Disclaimer
# #
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY # THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE. # SUCH DAMAGE.
# #
# #
# This software consists of contributions made by Digital Creations and # This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations. Specific # many individuals on behalf of Digital Creations. Specific
# attributions are listed in the accompanying credits file. # attributions are listed in the accompanying credits file.
# #
############################################################################## ##############################################################################
""" """
ZServer as a NT service. ZServer as a NT service.
The serice starts up and monitors a ZServer process. The serice starts up and monitors a ZServer process.
Features: Features:
* When you start the service it starts ZServer * When you start the service it starts ZServer
* When you stop the serivice it stops ZServer * When you stop the serivice it stops ZServer
* It monitors ZServer and restarts it if it exits abnormally * It monitors ZServer and restarts it if it exits abnormally
* If ZServer is shutdown from the web, the service stops. * If ZServer is shutdown from the web, the service stops.
* If ZServer cannot be restarted, the service stops. * If ZServer cannot be restarted, the service stops.
Usage: Usage:
Installation Installation
The ZServer service should be installed by the Zope Windows The ZServer service should be installed by the Zope Windows
installer. You can manually install, uninstall the service from installer. You can manually install, uninstall the service from
the commandline. the commandline.
ZService.py [options] install|update|remove|start [...] ZService.py [options] install|update|remove|start [...]
|stop|restart [...]|debug [...] |stop|restart [...]|debug [...]
Options for 'install' and 'update' commands only: Options for 'install' and 'update' commands only:
--username domain\username : The Username the service is to run --username domain\username : The Username the service is to run
under under
--password password : The password for the username --password password : The password for the username
--startup [manual|auto|disabled] : How the service starts, --startup [manual|auto|disabled] : How the service starts,
default = manual default = manual
Commands Commands
install : Installs the service install : Installs the service
update : Updates the service, use this when you change update : Updates the service, use this when you change
ZServer.py ZServer.py
remove : Removes the service remove : Removes the service
start : Starts the service, this can also be done from the start : Starts the service, this can also be done from the
services control panel services control panel
stop : Stops the service, this can also be done from the stop : Stops the service, this can also be done from the
services control panel services control panel
restart : Restarts the service restart : Restarts the service
debug : Runs the service in debug mode debug : Runs the service in debug mode
You can view the usage options by running ZServer.py without any You can view the usage options by running ZServer.py without any
arguments. arguments.
Note: you may have to register the Python service program first, Note: you may have to register the Python service program first,
win32\pythonservice.exe /register win32\pythonservice.exe /register
Starting Zope Starting Zope
Start Zope by clicking the 'start' button in the services control Start Zope by clicking the 'start' button in the services control
panel. You can set Zope to automatically start at boot time by panel. You can set Zope to automatically start at boot time by
choosing 'Auto' startup by clicking the 'statup' button. choosing 'Auto' startup by clicking the 'statup' button.
Stopping Zope Stopping Zope
Stop Zope by clicking the 'stop' button in the services control Stop Zope by clicking the 'stop' button in the services control
panel. You can also stop Zope through the web by going to the panel. You can also stop Zope through the web by going to the
Zope control panel and by clicking 'Shutdown'. Zope control panel and by clicking 'Shutdown'.
Event logging Event logging
Zope events are logged to the NT application event log. Use the Zope events are logged to the NT application event log. Use the
event viewer to keep track of Zope events. event viewer to keep track of Zope events.
Registry Settings Registry Settings
You can change how the service starts ZServer by editing a registry You can change how the service starts ZServer by editing a registry
key. key.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\
<Service Name>\Parameters\start <Service Name>\Parameters\start
The value of this key is the command which the service uses to The value of this key is the command which the service uses to
start ZServer. For example: start ZServer. For example:
"C:\Program Files\Zope\bin\python.exe" "C:\Program Files\Zope\bin\python.exe"
"C:\Program Files\Zope\z2.py" -w 8888 "C:\Program Files\Zope\z2.py" -w 8888
TODO: TODO:
* Integrate it into the Windows installer. * Integrate it into the Windows installer.
* Add ZLOG logging in addition to event log logging. * Add ZLOG logging in addition to event log logging.
* Make it easier to run multiple Zope services with one Zope install * Make it easier to run multiple Zope services with one Zope install
This script does for NT the same sort of thing zdaemon.py does for UNIX. This script does for NT the same sort of thing zdaemon.py does for UNIX.
Requires Python win32api extensions. Requires Python win32api extensions.
""" """
import sys
import win32api, win32serviceutil, win32service, win32event, win32process sys.path.append('./lib/win32')
try: import servicemanager import win32api, win32serviceutil, win32service, win32event, win32process
except: pass try: import servicemanager
import time, imp, sys except: pass
import time, imp, sys
try:
import App.version_txt try:
ZOPE_VERSION=App.version_txt.version_txt() import App.version_txt
except: ZOPE_VERSION=App.version_txt.version_txt()
ZOPE_VERSION='1.10.x' except:
ZOPE_VERSION='1.10.x'
# pythoncom and pywintypes are special, and require these hacks when
# we dont have a standard Python installation around. # pythoncom and pywintypes are special, and require these hacks when
# we dont have a standard Python installation around.
def magic_import(modulename, filename):
# by Mark Hammond def magic_import(modulename, filename):
try: # by Mark Hammond
# See if it does import first! try:
return __import__(modulename) # See if it does import first!
except ImportError: return __import__(modulename)
pass except ImportError:
# win32 can find the DLL name. pass
h = win32api.LoadLibrary(filename) # win32 can find the DLL name.
found = win32api.GetModuleFileName(h) h = win32api.LoadLibrary(filename)
# Python can load the module found = win32api.GetModuleFileName(h)
mod = imp.load_module(modulename, None, found, ('.dll', 'rb', imp.C_EXTENSION)) # Python can load the module
# inject it into the global module list. mod = imp.load_module(modulename, None, found, ('.dll', 'rb', imp.C_EXTENSION))
sys.modules[modulename] = mod # inject it into the global module list.
# And finally inject it into the namespace. sys.modules[modulename] = mod
globals()[modulename] = mod # And finally inject it into the namespace.
win32api.FreeLibrary(h) globals()[modulename] = mod
win32api.FreeLibrary(h)
magic_import('pywintypes','pywintypes15.dll')
magic_import('pywintypes','pywintypes15.dll')
class ZServerService(win32serviceutil.ServiceFramework):
_svc_name_ = "Zope%s" % ZOPE_VERSION class ZServerService(win32serviceutil.ServiceFramework):
_svc_display_name_ = "Zope (%s)" % ZOPE_VERSION _svc_name_ = "Zope%s" % ZOPE_VERSION
_svc_display_name_ = "Zope (%s)" % ZOPE_VERSION
restart_min_time=5 # if ZServer restarts before this many
# seconds then we have a problem, and restart_min_time=5 # if ZServer restarts before this many
# need to stop the service. # seconds then we have a problem, and
# need to stop the service.
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args) def __init__(self, args):
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None) win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
def SvcDoRun(self):
self.start_zserver() def SvcDoRun(self):
while 1: self.start_zserver()
rc=win32event.WaitForMultipleObjects( while 1:
(self.hWaitStop, self.hZServer), 0, win32event.INFINITE) rc=win32event.WaitForMultipleObjects(
if rc - win32event.WAIT_OBJECT_0 == 0: (self.hWaitStop, self.hZServer), 0, win32event.INFINITE)
break if rc - win32event.WAIT_OBJECT_0 == 0:
else: break
self.restart_zserver() else:
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING, 5000) self.restart_zserver()
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING, 5000)
def SvcStop(self):
servicemanager.LogInfoMsg('Stopping Zope.') def SvcStop(self):
try: servicemanager.LogInfoMsg('Stopping Zope.')
self.stop_zserver() try:
except: self.stop_zserver()
pass except:
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) pass
win32event.SetEvent(self.hWaitStop) self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def start_zserver(self):
result=win32process.CreateProcess(None, self.get_start_command(), def start_zserver(self):
None, None, 0, 0, None, None, win32process.STARTUPINFO()) result=win32process.CreateProcess(None, self.get_start_command(),
self.hZServer=result[0] None, None, 0, 0, None, None, win32process.STARTUPINFO())
self.last_start_time=time.time() self.hZServer=result[0]
servicemanager.LogInfoMsg('Starting Zope.') self.last_start_time=time.time()
servicemanager.LogInfoMsg('Starting Zope.')
def stop_zserver(self):
win32process.TerminateProcess(self.hZServer,0) def stop_zserver(self):
win32process.TerminateProcess(self.hZServer,0)
def restart_zserver(self):
if time.time() - self.last_start_time < self.restart_min_time: def restart_zserver(self):
servicemanager.LogErrorMsg('Zope died and could not be restarted.') if time.time() - self.last_start_time < self.restart_min_time:
self.SvcStop() servicemanager.LogErrorMsg('Zope died and could not be restarted.')
code=win32process.GetExitCodeProcess(self.hZServer) self.SvcStop()
if code == 0: code=win32process.GetExitCodeProcess(self.hZServer)
# Exited with a normal status code, if code == 0:
# assume that shutdown is intentional. # Exited with a normal status code,
self.SvcStop() # assume that shutdown is intentional.
else: self.SvcStop()
servicemanager.LogWarningMsg('Restarting Zope.') else:
self.start_zserver() servicemanager.LogWarningMsg('Restarting Zope.')
self.start_zserver()
def get_start_command(self):
return win32serviceutil.GetServiceCustomOption(self,'start') def get_start_command(self):
return win32serviceutil.GetServiceCustomOption(self,'start')
def set_start_command(value):
"sets the ZServer start command" def set_start_command(value):
win32serviceutil.SetServiceCustomOption(ZServerService,'start',value) "sets the ZServer start command"
win32serviceutil.SetServiceCustomOption(ZServerService,'start',value)
if __name__=='__main__':
win32serviceutil.HandleCommandLine(ZServerService) if __name__=='__main__':
if sys.argv[1]=='install': win32serviceutil.HandleCommandLine(ZServerService)
if win32serviceutil.GetServiceCustomOption(ZServerService,'start') is None: if sys.argv[1]=='install':
import string, os.path if win32serviceutil.GetServiceCustomOption(ZServerService,'start') is None:
home=string.split(sys.argv[0],'ZServer')[0] import string, os.path
command='"%s" "%s" -S' % (sys.executable, os.path.join(home,'z2.py')) home=string.split(sys.argv[0],'ZServer')[0]
set_start_command(command) command='"%s" "%s" -S' % (sys.executable, os.path.join(home,'z2.py'))
print "Setting ZServer start command to:", command set_start_command(command)
print "Setting ZServer start command to:", command
############################################################################## ##############################################################################
# #
# Zope Public License (ZPL) Version 1.0 # Zope Public License (ZPL) Version 1.0
# ------------------------------------- # -------------------------------------
# #
# Copyright (c) Digital Creations. All rights reserved. # Copyright (c) Digital Creations. All rights reserved.
# #
# This license has been certified as Open Source(tm). # This license has been certified as Open Source(tm).
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are # modification, are permitted provided that the following conditions are
# met: # met:
# #
# 1. Redistributions in source code must retain the above copyright # 1. Redistributions in source code must retain the above copyright
# notice, this list of conditions, and the following disclaimer. # notice, this list of conditions, and the following disclaimer.
# #
# 2. Redistributions in binary form must reproduce the above copyright # 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in # notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the # the documentation and/or other materials provided with the
# distribution. # distribution.
# #
# 3. Digital Creations requests that attribution be given to Zope # 3. Digital Creations requests that attribution be given to Zope
# in any manner possible. Zope includes a "Powered by Zope" # in any manner possible. Zope includes a "Powered by Zope"
# button that is installed by default. While it is not a license # button that is installed by default. While it is not a license
# violation to remove this button, it is requested that the # violation to remove this button, it is requested that the
# attribution remain. A significant investment has been put # attribution remain. A significant investment has been put
# into Zope, and this effort will continue if the Zope community # into Zope, and this effort will continue if the Zope community
# continues to grow. This is one way to assure that growth. # continues to grow. This is one way to assure that growth.
# #
# 4. All advertising materials and documentation mentioning # 4. All advertising materials and documentation mentioning
# features derived from or use of this software must display # features derived from or use of this software must display
# the following acknowledgement: # the following acknowledgement:
# #
# "This product includes software developed by Digital Creations # "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment # for use in the Z Object Publishing Environment
# (http://www.zope.org/)." # (http://www.zope.org/)."
# #
# In the event that the product being advertised includes an # In the event that the product being advertised includes an
# intact Zope distribution (with copyright and license included) # intact Zope distribution (with copyright and license included)
# then this clause is waived. # then this clause is waived.
# #
# 5. Names associated with Zope or Digital Creations must not be used to # 5. Names associated with Zope or Digital Creations must not be used to
# endorse or promote products derived from this software without # endorse or promote products derived from this software without
# prior written permission from Digital Creations. # prior written permission from Digital Creations.
# #
# 6. Modified redistributions of any form whatsoever must retain # 6. Modified redistributions of any form whatsoever must retain
# the following acknowledgment: # the following acknowledgment:
# #
# "This product includes software developed by Digital Creations # "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment # for use in the Z Object Publishing Environment
# (http://www.zope.org/)." # (http://www.zope.org/)."
# #
# Intact (re-)distributions of any official Zope release do not # Intact (re-)distributions of any official Zope release do not
# require an external acknowledgement. # require an external acknowledgement.
# #
# 7. Modifications are encouraged but must be packaged separately as # 7. Modifications are encouraged but must be packaged separately as
# patches to official Zope releases. Distributions that do not # patches to official Zope releases. Distributions that do not
# clearly separate the patches from the original work must be clearly # clearly separate the patches from the original work must be clearly
# labeled as unofficial distributions. Modifications which do not # labeled as unofficial distributions. Modifications which do not
# carry the name Zope may be packaged in any form, as long as they # carry the name Zope may be packaged in any form, as long as they
# conform to all of the clauses above. # conform to all of the clauses above.
# #
# #
# Disclaimer # Disclaimer
# #
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY # THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE. # SUCH DAMAGE.
# #
# #
# This software consists of contributions made by Digital Creations and # This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations. Specific # many individuals on behalf of Digital Creations. Specific
# attributions are listed in the accompanying credits file. # attributions are listed in the accompanying credits file.
# #
############################################################################## ##############################################################################
""" """
ZServer as a NT service. ZServer as a NT service.
The serice starts up and monitors a ZServer process. The serice starts up and monitors a ZServer process.
Features: Features:
* When you start the service it starts ZServer * When you start the service it starts ZServer
* When you stop the serivice it stops ZServer * When you stop the serivice it stops ZServer
* It monitors ZServer and restarts it if it exits abnormally * It monitors ZServer and restarts it if it exits abnormally
* If ZServer is shutdown from the web, the service stops. * If ZServer is shutdown from the web, the service stops.
* If ZServer cannot be restarted, the service stops. * If ZServer cannot be restarted, the service stops.
Usage: Usage:
Installation Installation
The ZServer service should be installed by the Zope Windows The ZServer service should be installed by the Zope Windows
installer. You can manually install, uninstall the service from installer. You can manually install, uninstall the service from
the commandline. the commandline.
ZService.py [options] install|update|remove|start [...] ZService.py [options] install|update|remove|start [...]
|stop|restart [...]|debug [...] |stop|restart [...]|debug [...]
Options for 'install' and 'update' commands only: Options for 'install' and 'update' commands only:
--username domain\username : The Username the service is to run --username domain\username : The Username the service is to run
under under
--password password : The password for the username --password password : The password for the username
--startup [manual|auto|disabled] : How the service starts, --startup [manual|auto|disabled] : How the service starts,
default = manual default = manual
Commands Commands
install : Installs the service install : Installs the service
update : Updates the service, use this when you change update : Updates the service, use this when you change
ZServer.py ZServer.py
remove : Removes the service remove : Removes the service
start : Starts the service, this can also be done from the start : Starts the service, this can also be done from the
services control panel services control panel
stop : Stops the service, this can also be done from the stop : Stops the service, this can also be done from the
services control panel services control panel
restart : Restarts the service restart : Restarts the service
debug : Runs the service in debug mode debug : Runs the service in debug mode
You can view the usage options by running ZServer.py without any You can view the usage options by running ZServer.py without any
arguments. arguments.
Note: you may have to register the Python service program first, Note: you may have to register the Python service program first,
win32\pythonservice.exe /register win32\pythonservice.exe /register
Starting Zope Starting Zope
Start Zope by clicking the 'start' button in the services control Start Zope by clicking the 'start' button in the services control
panel. You can set Zope to automatically start at boot time by panel. You can set Zope to automatically start at boot time by
choosing 'Auto' startup by clicking the 'statup' button. choosing 'Auto' startup by clicking the 'statup' button.
Stopping Zope Stopping Zope
Stop Zope by clicking the 'stop' button in the services control Stop Zope by clicking the 'stop' button in the services control
panel. You can also stop Zope through the web by going to the panel. You can also stop Zope through the web by going to the
Zope control panel and by clicking 'Shutdown'. Zope control panel and by clicking 'Shutdown'.
Event logging Event logging
Zope events are logged to the NT application event log. Use the Zope events are logged to the NT application event log. Use the
event viewer to keep track of Zope events. event viewer to keep track of Zope events.
Registry Settings Registry Settings
You can change how the service starts ZServer by editing a registry You can change how the service starts ZServer by editing a registry
key. key.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\
<Service Name>\Parameters\start <Service Name>\Parameters\start
The value of this key is the command which the service uses to The value of this key is the command which the service uses to
start ZServer. For example: start ZServer. For example:
"C:\Program Files\Zope\bin\python.exe" "C:\Program Files\Zope\bin\python.exe"
"C:\Program Files\Zope\z2.py" -w 8888 "C:\Program Files\Zope\z2.py" -w 8888
TODO: TODO:
* Integrate it into the Windows installer. * Integrate it into the Windows installer.
* Add ZLOG logging in addition to event log logging. * Add ZLOG logging in addition to event log logging.
* Make it easier to run multiple Zope services with one Zope install * Make it easier to run multiple Zope services with one Zope install
This script does for NT the same sort of thing zdaemon.py does for UNIX. This script does for NT the same sort of thing zdaemon.py does for UNIX.
Requires Python win32api extensions. Requires Python win32api extensions.
""" """
import sys
import win32api, win32serviceutil, win32service, win32event, win32process sys.path.append('./lib/win32')
try: import servicemanager import win32api, win32serviceutil, win32service, win32event, win32process
except: pass try: import servicemanager
import time, imp, sys except: pass
import time, imp, sys
try:
import App.version_txt try:
ZOPE_VERSION=App.version_txt.version_txt() import App.version_txt
except: ZOPE_VERSION=App.version_txt.version_txt()
ZOPE_VERSION='1.10.x' except:
ZOPE_VERSION='1.10.x'
# pythoncom and pywintypes are special, and require these hacks when
# we dont have a standard Python installation around. # pythoncom and pywintypes are special, and require these hacks when
# we dont have a standard Python installation around.
def magic_import(modulename, filename):
# by Mark Hammond def magic_import(modulename, filename):
try: # by Mark Hammond
# See if it does import first! try:
return __import__(modulename) # See if it does import first!
except ImportError: return __import__(modulename)
pass except ImportError:
# win32 can find the DLL name. pass
h = win32api.LoadLibrary(filename) # win32 can find the DLL name.
found = win32api.GetModuleFileName(h) h = win32api.LoadLibrary(filename)
# Python can load the module found = win32api.GetModuleFileName(h)
mod = imp.load_module(modulename, None, found, ('.dll', 'rb', imp.C_EXTENSION)) # Python can load the module
# inject it into the global module list. mod = imp.load_module(modulename, None, found, ('.dll', 'rb', imp.C_EXTENSION))
sys.modules[modulename] = mod # inject it into the global module list.
# And finally inject it into the namespace. sys.modules[modulename] = mod
globals()[modulename] = mod # And finally inject it into the namespace.
win32api.FreeLibrary(h) globals()[modulename] = mod
win32api.FreeLibrary(h)
magic_import('pywintypes','pywintypes15.dll')
magic_import('pywintypes','pywintypes15.dll')
class ZServerService(win32serviceutil.ServiceFramework):
_svc_name_ = "Zope%s" % ZOPE_VERSION class ZServerService(win32serviceutil.ServiceFramework):
_svc_display_name_ = "Zope (%s)" % ZOPE_VERSION _svc_name_ = "Zope%s" % ZOPE_VERSION
_svc_display_name_ = "Zope (%s)" % ZOPE_VERSION
restart_min_time=5 # if ZServer restarts before this many
# seconds then we have a problem, and restart_min_time=5 # if ZServer restarts before this many
# need to stop the service. # seconds then we have a problem, and
# need to stop the service.
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args) def __init__(self, args):
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None) win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
def SvcDoRun(self):
self.start_zserver() def SvcDoRun(self):
while 1: self.start_zserver()
rc=win32event.WaitForMultipleObjects( while 1:
(self.hWaitStop, self.hZServer), 0, win32event.INFINITE) rc=win32event.WaitForMultipleObjects(
if rc - win32event.WAIT_OBJECT_0 == 0: (self.hWaitStop, self.hZServer), 0, win32event.INFINITE)
break if rc - win32event.WAIT_OBJECT_0 == 0:
else: break
self.restart_zserver() else:
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING, 5000) self.restart_zserver()
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING, 5000)
def SvcStop(self):
servicemanager.LogInfoMsg('Stopping Zope.') def SvcStop(self):
try: servicemanager.LogInfoMsg('Stopping Zope.')
self.stop_zserver() try:
except: self.stop_zserver()
pass except:
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) pass
win32event.SetEvent(self.hWaitStop) self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def start_zserver(self):
result=win32process.CreateProcess(None, self.get_start_command(), def start_zserver(self):
None, None, 0, 0, None, None, win32process.STARTUPINFO()) result=win32process.CreateProcess(None, self.get_start_command(),
self.hZServer=result[0] None, None, 0, 0, None, None, win32process.STARTUPINFO())
self.last_start_time=time.time() self.hZServer=result[0]
servicemanager.LogInfoMsg('Starting Zope.') self.last_start_time=time.time()
servicemanager.LogInfoMsg('Starting Zope.')
def stop_zserver(self):
win32process.TerminateProcess(self.hZServer,0) def stop_zserver(self):
win32process.TerminateProcess(self.hZServer,0)
def restart_zserver(self):
if time.time() - self.last_start_time < self.restart_min_time: def restart_zserver(self):
servicemanager.LogErrorMsg('Zope died and could not be restarted.') if time.time() - self.last_start_time < self.restart_min_time:
self.SvcStop() servicemanager.LogErrorMsg('Zope died and could not be restarted.')
code=win32process.GetExitCodeProcess(self.hZServer) self.SvcStop()
if code == 0: code=win32process.GetExitCodeProcess(self.hZServer)
# Exited with a normal status code, if code == 0:
# assume that shutdown is intentional. # Exited with a normal status code,
self.SvcStop() # assume that shutdown is intentional.
else: self.SvcStop()
servicemanager.LogWarningMsg('Restarting Zope.') else:
self.start_zserver() servicemanager.LogWarningMsg('Restarting Zope.')
self.start_zserver()
def get_start_command(self):
return win32serviceutil.GetServiceCustomOption(self,'start') def get_start_command(self):
return win32serviceutil.GetServiceCustomOption(self,'start')
def set_start_command(value):
"sets the ZServer start command" def set_start_command(value):
win32serviceutil.SetServiceCustomOption(ZServerService,'start',value) "sets the ZServer start command"
win32serviceutil.SetServiceCustomOption(ZServerService,'start',value)
if __name__=='__main__':
win32serviceutil.HandleCommandLine(ZServerService) if __name__=='__main__':
if sys.argv[1]=='install': win32serviceutil.HandleCommandLine(ZServerService)
if win32serviceutil.GetServiceCustomOption(ZServerService,'start') is None: if sys.argv[1]=='install':
import string, os.path if win32serviceutil.GetServiceCustomOption(ZServerService,'start') is None:
home=string.split(sys.argv[0],'ZServer')[0] import string, os.path
command='"%s" "%s" -S' % (sys.executable, os.path.join(home,'z2.py')) home=string.split(sys.argv[0],'ZServer')[0]
set_start_command(command) command='"%s" "%s" -S' % (sys.executable, os.path.join(home,'z2.py'))
print "Setting ZServer start command to:", command set_start_command(command)
print "Setting ZServer start command to:", command
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment