[python-win32] Re: Windows service features and Python
Imre András Róbert
beast at ludens.elte.hu
Thu Aug 5 21:57:35 CEST 2004
Hello list,
I always forgot attaching what I promise...
Sorry,
András
Thursday, August 5, 2004, 9:48:06 PM, you wrote:
> Hello list,
> I'm transforming some Python code into a Windows
> service. I started with pywin32-202.win32-py2.2.exe,
> and investigated the demo pipeTestService. This
> worked fine, so I started converting my code, with
> no paticular Windows system programming experience.
> After reading through the help, the newsgroups and
> searching on the web, I still have the following questions:
> Q1) How can I make my Python service support pause/
> continue? Implementing SvcPause() and SvcContinue()
> seems to be not enough, as I get 'Could not pause
> ... service on Local Computer. The service did not
> return an error. ...' dialog despite that the
> SvcPause() method is executed. After this dialog
> I found that the service was stopped, ending within
> SvcDoRun(). Please refer to the attached code.
> Q2) How can I register my own event IDs/categories? I don't
> know where/how to define my own IDs/cats. The demo seems
> to support two IDs, servicemanager.PYS_SERVICE_STARTED and
> servicemanager.PYS_SERVICE_STOPPED.
> Q3) How can I add counters to the Python service? Looking at
> the files perf_install.ini and perf_install.h, this
> could be possible, but after install I do not see these
> counters in PerfMon. I do not see the way these files
> are connected to the service demo source code... Maybe
> these are already installed as the readme indicates,
> but where should I look?
> After all the package is quite useful with the start/stop
> service feature itself, but I would welcome some fancy stuff
> as well...
-------------- next part --------------
import win32serviceutil, win32service
import pywintypes, win32con, winerror
# Use "import *" to keep this looking as much as a "normal" service
# as possible. Real code shouldn't do this.
from win32event import *
from win32file import *
from win32pipe import *
from win32api import *
from ntsecuritycon import *
import traceback
import thread
def ApplyIgnoreError(fn, args):
try:
return apply(fn, args)
except error: # Ignore win32api errors.
return None
class PythonTestService(win32serviceutil.ServiceFramework):
_svc_name_ = "PythonTestService"
_svc_display_name_ = "Python Test Service"
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = CreateEvent(None, 0, 0, None)
self.overlapped = pywintypes.OVERLAPPED()
self.overlapped.hEvent = CreateEvent(None,0,0,None)
# self.thread_handles = []
def SvcStop(self):
import servicemanager
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
12121,
(self._svc_name_, 'SvcStop')
)
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
SetEvent(self.hWaitStop)
def SvcPause(self):
import servicemanager
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
11111,
(self._svc_name_, 'SvcPause')
)
self.ReportServiceStatus(win32service.SERVICE_PAUSE_PENDING)
SetEvent(self.hWaitStop)
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
11111,
(self._svc_name_, 'SvcPause end')
)
def SvcContinue(self):
import servicemanager
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
22222,
(self._svc_name_, 'SvcContinue')
)
self.ReportServiceStatus(win32service.SERVICE_CONTINUE_PENDING)
SetEvent(self.hWaitStop)
def SvcInterrogate(self):
import servicemanager
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
33333,
(self._svc_name_, 'SvcInterrogate')
)
self.ReportServiceStatus(win32service.SERVICE_INTERROGATE)
SetEvent(self.hWaitStop)
def SvcShutdown(self):
import servicemanager
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
44444,
(self._svc_name_, 'SvcShutdown')
)
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
SetEvent(self.hWaitStop)
def SvcOther(self, control):
import servicemanager
servicemanager.LogMsg(
servicemanager.EVENTLOG_WARNING_TYPE,
55555,
(self._svc_name_, "SvcOther, code %d" % (control))
)
def SvcDoRun(self):
# Write an event log record - in debug mode we will also
# see this message printed.
import servicemanager
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
12345,
(self._svc_name_, 'SvcDoRun')
)
while 1:
print "."
rc = WaitForMultipleObjects((self.hWaitStop, self.overlapped.hEvent), 0, INFINITE)
if rc==WAIT_OBJECT_0:
# Stop event
break
Sleep(500)
# Sleep to ensure that any new threads are in the list, and then
# wait for all current threads to finish.
# What is a better way?
# Sleep(500)
# while self.thread_handles:
# self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING, 5000)
# print "Waiting for %d threads to finish..." % (len(self.thread_handles))
# WaitForMultipleObjects(self.thread_handles, 1, 3000)
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING, 5000)
# Write another event log record.
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
54321,
(self._svc_name_, 'SvcDoRun ends')
)
if __name__=='__main__':
win32serviceutil.HandleCommandLine(PythonTestService)
More information about the Python-win32
mailing list