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 [email protected] http://mail.python.org/mailman/listinfo/python-win32
