I run a Cherrypy app as a Windows service, so I imagine that the
process of converting a TG app to run as a service will be similar.  If
you haven't already done so, download the python win32utils package -
it is a must have on the Win platform.

The code:
--------------------------------------------------------------------------------------------------
service.py

import sys, os
import win32serviceutil, win32service
import main

class ReportingService(win32serviceutil.ServiceFramework):
    """NT Service."""

    _svc_name_ = "Your Service Name"
    _svc_display_name_ = "Your Service Display Name"

    def SvcDoRun(self):
        os.chdir("path/to/your/project")  # VERY IMPORTANT!!!
        sys.stdout = open('./stdout.log','a')
        sys.stderr = open('./sterr.log','a')
        main.start()

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        main.stop()

if __name__ == '__main__':
    win32serviceutil.HandleCommandLine(ReportingService)
---------------------------------------------------------------------------------------------------------

A couple of notes:

1. This file needs to be placed in the same directory as the
<project_name>-start.py file generated by TG.

2. The os.chdir() command in the SvcDoRun method is very important.
When the service starts, it has no idea where your code lives.  This
line will help Python find your TG app and code.  This should point to
the directory where the service.py file is located.

3.  The two stdout and stderr statements are necessary because without
them, your service will crash.  This occurs because when your app is
running as a service, there is no sys.stdout or sys.stderr, so all
standard output gets held in a buffer that will eventually run out of
room and crash your service.  Redirecting the standard output to these
files will alleviate the situation.

4. The "main" import:  I usually create a couple of functions (stop,
start) in a file called main.py that actually starts my app (this file
is placed in the same directory as service.py).  A TG main file would
probably look like the following (from a v 0.84 TG app):

-------------------------------------------------------------------------------------------------------------------
main.py

import pkg_resources
pkg_resources.require("TurboGears")

import cherrypy
from os.path import *
import sys

def start():
    if len(sys.argv) > 1:
        cherrypy.config.update(file=sys.argv[1])
    elif exists(join(dirname(__file__), "setup.py")):
        cherrypy.config.update(file="dev.cfg")
    else:
        cherrypy.config.update(file="prod.cfg")

    from <project_name>.controllers import Root

    cherrypy.root = Root()
    cherrypy.server.start()

def stop()
    cherrypy.server.stop()
-----------------------------------------------------------------------------------------------------------------

5. Installation
Open a command prompt and navigate to the directory where service.py is
located.  Issue the following command:

service.py install

You should receive a note saying that the service was installed.  If
successful, you should be able to see the app in the services window
under the name you specified in the _svc_display_name_ field in
service.py.  It will be installed under the local account, and you will
have to switch it to automatically start when the computer starts.

Other usefull commands:

service.py remove (removes the service)
service.py start (starts the service - can also be done from the
services window)
service.py stop (stops the service - can also be done from the services
window)

Again, I haven't tried installing a TG app as a windows service yet,
but I imagine that the code will be very similar to what I've posted
above.

Let me know if you have any questions.

Sean

[EMAIL PROTECTED] wrote:
> I've got a sweet (at least I think so) Turbogears app that I'm ready to
> role into production. It needs to run on a Windows server because it
> does some DCOM related stuff.  Does anyone have any experience, yet,
> with converting their app to a windows service so it runs without a
> logged-in user?  
> 
> Thanks
> Dennis

Reply via email to