On 4/6/06, Michael Li <[EMAIL PROTECTED]> wrote: > > Although it is not obvious from Twisted documentation it is trivial to > > run an application as a windows service as long as you use *.tac files > > to build it. > > Can you share your code ? > > I also have an application using Twisted, but I got problems to run as a > service.
I am using py2exe with custom setup.py file. Additionally I have startup.tac and winservice.py - startup.tac - if you know Twisted then you know what goes into startup.tac :-). - winservice.py - is the stub file that gets compiled into winservice.exe. This is the file that you will register with Windows. winservice.exe -h will list all the options. I do not remember them at them moment. - setup.py - is almost standard setup file. You run it with python setup.py py2exe. The trick is to list all required modules explicitly. I list all except the modules that hold my Twisted application logic. The advantage is that I can replace the modules without recompiling. Only restart the service and the bug fix is implemented. Your admin will love you for that :-) The only problem is if you missed a required module the service will die silently when starting. Luckily the Python traceback gets recorded in Windows Application Log. Check it to see what the service is complaining about, add the missing part, rinse and repeat. See the attached files for an example. The original idea comes from: http://twistedmatrix.com/trac/browser/sandbox/moonfallen/ See it for more documentation.
import sys import os import win32serviceutil, win32service basecf = "startup.tac" cftype = "python" svcname = "dispatcher" display = "Twisted Task Dispatcher" reactortype = "default" class ServiceControl(win32serviceutil.ServiceFramework): _svc_name_ = svcname _svc_display_name_ = display def SvcDoRun(self): from twisted.application import app app.installReactor(reactortype) from twisted.internet import reactor from twisted.application import service from twisted.python import util, log, logfile # look for a readable config file for cf in (util.sibpath(sys.executable, basecf), util.sibpath(__file__, basecf), basecf): try: open(cf, 'r').close() except EnvironmentError: continue else: startdir = os.path.dirname(cf) os.chdir(startdir) sys.path.insert(0, startdir) break lf = logfile.LogFile('%s.log' %svcname, 'logs') log.startLogging(lf) log.msg("Loading application from %s" % cf) service_app = service.loadApplication(cf, cftype) app.startApplication(service_app , False) reactor.run(installSignalHandlers=0) def SvcStop(self): self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) from twisted.internet import reactor reactor.callFromThread(reactor.stop) if __name__ == '__main__': win32serviceutil.HandleCommandLine(ServiceControl)
startup.tac
Description: Binary data
import sys # without this section taskscheduler can not be found import py2exe.mf as modulefinder import win32com for p in win32com.__path__[1:]: modulefinder.AddPackagePath('win32com', p) for extra in ['win32com.taskscheduler']: __import__(extra) m = sys.modules[extra] for p in m.__path__[1:]: modulefinder.AddPackagePath(extra, p) from distutils.core import setup import py2exe setup(service = ['winservice'], zipfile = "lib/library.zip", data_files = (('', ['startup.tac', 'config.ini', 'backend.py', 'dbloader.py', 'dispatcher.py', 'xlsparser.py', ]), ('wsdl', ['wsdl/MFISLoader.wsdl',]), ('logs', []), ), options = {'global': {'verbose': '0'}, 'py2exe': {'optimize': 2, 'dist_dir': 'dispatcher', 'excludes': ['perfmon'], 'dll_excludes': [], 'packages': ['twisted.application', 'twisted.python', 'twisted.web', 'elementtree', 'pyExcelerator', ], 'includes': ['datetime', 'pythoncom', 'cElementTree', 'cx_Oracle', 'twisted.mail.smtp', 'utils.batch', 'win32com.taskscheduler.taskscheduler', ], } }, )
_______________________________________________ Python-win32 mailing list Python-win32@python.org http://mail.python.org/mailman/listinfo/python-win32