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)

Attachment: 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

Reply via email to