ASPN ActiveState Programmer Network  
ActiveState, a division of Sophos
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups
Submit Recipe
My Recipes

All Recipes
All Cookbooks


View by Category

Title: Win Services helper
Submitter: Louis RIVIERE (other recipes)
Last Updated: 2008/04/11
Version no: 1.1
Category: System

 

5 stars 4 vote(s)


Description:

A simple way to implement Windows Service.

Source: Text Source

# winservice.py

from os.path import splitext, abspath
from sys import modules

import win32serviceutil
import win32service
import win32event
import win32api

class Service(win32serviceutil.ServiceFramework):
	_svc_name_ = '_unNamed'
	_svc_display_name_ = '_Service Template'
	def __init__(self, *args):
		win32serviceutil.ServiceFramework.__init__(self, *args)
		self.log('init')
		self.stop_event = win32event.CreateEvent(None, 0, 0, None)
	def log(self, msg):
		import servicemanager
		servicemanager.LogInfoMsg(str(msg))
        def sleep(self, sec):
                win32api.Sleep(sec*1000, True)
	def SvcDoRun(self):
		self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
		try:
			self.ReportServiceStatus(win32service.SERVICE_RUNNING)
			self.log('start')
			self.start()
			self.log('wait')
			win32event.WaitForSingleObject(self.stop_event, win32event.INFINITE)
			self.log('done')
		except Exception, x:
			self.log('Exception : %s' % x)
			self.SvcStop()
	def SvcStop(self):
		self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
		self.log('stopping')
		self.stop()
		self.log('stopped')
		win32event.SetEvent(self.stop_event)
		self.ReportServiceStatus(win32service.SERVICE_STOPPED)
	# to be overridden
	def start(self): pass
	# to be overridden
	def stop(self): pass

def instart(cls, name, display_name=None, stay_alive=True):
    '''
        Install and  Start (auto) a Service
            
            cls : the class (derived from Service) that implement the Service
            name : Service name
            display_name : the name displayed in the service manager
            stay_alive : Service will stop on logout if False
    '''
    cls._svc_name_ = name
    cls._svc_display_name_ = display_name or name
    try:
        module_path=modules[cls.__module__].__file__
    except AttributeError:
        # maybe py2exe went by
        from sys import executable
        module_path=executable
    module_file=splitext(abspath(module_path))[0]
    cls._svc_reg_class_ = '%s.%s' % (module_file, cls.__name__)
    if stay_alive: win32api.SetConsoleCtrlHandler(lambda x: True, True)
    try:
        win32serviceutil.InstallService(
                cls._svc_reg_class_,
                cls._svc_name_,
                cls._svc_display_name_,
                startType=win32service.SERVICE_AUTO_START
                )
        print 'Install ok'
        win32serviceutil.StartService(
                cls._svc_name_
                )
        print 'Start ok'
    except Exception, x:
        print str(x)

#
#
#
#
##### TEST MODULE
#
#
#
#

# winservice_test.py
from winservice import Service, instart

class Test(Service):
    def start(self):
        self.runflag=True
        while self.runflag:
            self.sleep(10)
            self.log("I'm alive ...")
    def stop(self):
        self.runflag=False
        self.log("I'm done")

instart(Test, 'aTest', 'Python Service Test')

Discussion:

Tested on Win XP only.

Patch for py2exe from Franck VINCENT



Add comment

Number of comments: 5

Method for service removal?, Matt Keranen, 2008/03/20
What steps would remove a service registered by this code from the registry?
Add comment

Service management, Louis RIVIERE, 2008/03/21
A Service is just a regular Windows Service, you can handle it like any other service running on your system.
You can start/stop/... it from the Services Manager, in which you will see the _svc_display_name of your Service.
You can handle it from a console with the NET or the SC commands.
Note that these commands, unlike the Windows Service Manager, use the _svc_name.
So, if you've install a Service like that:
>>> instart(MyServiceClass, 'myservice')
You can stop it like that :
>>> net stop myservice
You can remove like that :
>>> sc delete myservice

Add comment

don't work with a binary compiled with py2exe, franck vincent, 2008/03/28
take the same code, compile it with py2exe and you will have this error:

Traceback (most recent call last):
  File "test.py", line 14, in 
    instart(Test, 'aTest', 'Python Service Test')
  File "winservice.pyc", line 59, in instart

AttributeError: 'module' object has no attribute '__file__'
Any idea ?
Add comment

current compiled executable path/name, franck vincent, 2008/04/08
The error below because __file__ attributes is no longer available when you are executing the binary.

You have to use

"sys.executable"

rather than

"modules[cls.__module__].__file__"

Below the code i used:

if hasattr(modules[cls.__module__],'__file__'):
        cmod=modules[cls.__module__].__file__
    else:
        cmod=sys.executable
    module_file=splitext(abspath(cmod))[0]
    cls._svc_reg_class_ = '%s.%s' % (module_file, cls.__name__)

Add comment

whereAmI when i'm compiled ?, franck vincent, 2008/04/08
Interesting stuff here:

http://www.py2exe.org/index.cgi/WhereAmI
Add comment



Highest rated recipes:

1. A simple XML-RPC server

2. Web service accessible ...

3. Wrapping template engine ...

4. Assignment in expression

5. SOLVING THE METACLASS ...

6. Povray for python

7. Calling Windows API ...

8. Generic filter logic ...

9. Function Decorators by ...

10. MS SQL Server log monitor




Privacy Policy | Email Opt-out | Feedback | Syndication
© 2006 ActiveState Software Inc. All rights reserved.