[Zope-Checkins] CVS: Zope/lib/python/nt_svcutils - service.py:1.4
Jeremy Hylton
jeremy at zope.com
Tue Jan 13 17:37:03 EST 2004
Update of /cvs-repository/Zope/lib/python/nt_svcutils
In directory cvs.zope.org:/tmp/cvs-serv17838/Zope/lib/python/nt_svcutils
Modified Files:
service.py
Log Message:
Checkpoint of wrapper for uncoperative programs.
Adds an option to spawn a process and capture its I/O. Just a
checkpoint because it doesn't do anything with the captured I/O yet.
=== Zope/lib/python/nt_svcutils/service.py 1.3 => 1.4 ===
--- Zope/lib/python/nt_svcutils/service.py:1.3 Tue Jan 13 14:32:17 2004
+++ Zope/lib/python/nt_svcutils/service.py Tue Jan 13 17:37:02 2004
@@ -14,10 +14,15 @@
"""Windows Services installer/controller for Zope/ZEO/ZRS instance homes"""
-import win32serviceutil
-import win32service
+import win32api
+import win32con
import win32event
+import win32file
+import win32pipe
import win32process
+import win32security
+import win32service
+import win32serviceutil
import pywintypes
import time
import os
@@ -49,6 +54,9 @@
r'"C:\Program Files\Zope-2.7.0-a1\lib\python\Zope\Startup\run.py" '
r'-C "C:\Zope-Instance\etc\zope.conf"'
)
+
+ capture_io = False
+ log_file = None
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
@@ -69,9 +77,12 @@
win32event.SetEvent(self.hWaitStop)
def createProcess(self, cmd):
- return win32process.CreateProcess(
- None, cmd, None, None, 0, 0, None, None,
- win32process.STARTUPINFO())
+ if self.capture_io:
+ return self.createProcessCaptureIO(cmd)
+ else:
+ return win32process.CreateProcess(
+ None, cmd, None, None, 0, 0, None, None,
+ win32process.STARTUPINFO()), None
def logmsg(self, event):
# log a service event using servicemanager.LogMsg
@@ -124,12 +135,14 @@
while 1:
start_time = time.time()
- info = self.createProcess(self.start_cmd)
+ info, handles = self.createProcess(self.start_cmd)
+ # XXX integrate handles into the wait and make a loop
+ # that reads data and writes it into a logfile
self.hZope = info[0] # the pid
if backoff_interval > BACKOFF_INITIAL_INTERVAL:
self.info("created process")
rc = win32event.WaitForMultipleObjects(
- (self.hWaitStop, self.hZope), 0, win32event.INFINITE)
+ (self.hWaitStop, self.hZope) + handles, 0, win32event.INFINITE)
if rc == win32event.WAIT_OBJECT_0:
# user sent a stop service request
self.SvcStop()
@@ -161,8 +174,51 @@
backoff_cumulative += backoff_interval
backoff_interval *= 2
-
self.logmsg(servicemanager.PYS_SERVICE_STOPPED)
+
+ def createProcessCaptureIO(self, cmd):
+ stdin = self.newPipe()
+ stdout = self.newPipe()
+ stderr = self.newPipe()
+
+ si = win32process.STARTUPINFO()
+ si.hStdInput = stdin[0]
+ si.hStdOutput = stdout[1]
+ si.hStdError = stderr[1]
+ si.dwFlags = (win32process.STARTF_USESTDHANDLES
+ | win32process.STARTF_USESHOWWINDOW)
+ si.wShowWindow = win32con.SW_HIDE
+
+ c_stdin = self.dup(stdin[1])
+ c_stdout = self.dup(stdout[0])
+ c_stderr = self.dup(stderr[0])
+
+ # pass True to allow handles to be inherited. Inheritance is
+ # problematic in general, but should work in the controlled
+ # circumstances of a service process.
+ info = win32process.CreateProcess(None, cmd, None, None, True, 0,
+ None, None, si)
+
+ win32file.CloseHandle(stdin[0])
+ win32file.CloseHandle(stdout[1])
+ win32file.CloseHandle(stderr[1])
+
+ return info, (c_stdin, c_stdout, c_stderr)
+
+ def newPipe(self):
+ sa = win32security.SECURITY_ATTRIBUTES()
+ sa.bInheritHandle = True
+ return win32pipe.CreatePipe(sa, 0)
+
+ def dup(self, pipe):
+ # create a duplicate handle that is not inherited, so that
+ # it can be closed in the parent. close the original pipe in
+ # the process.
+ pid = win32api.GetCurrentProcess()
+ dup = win32api.DuplicateHandle(pid, pipe, pid, 0, 0,
+ win32con.DUPLICATE_SAME_ACCESS)
+ win32file.CloseHandle(pipe)
+ return dup
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(Service)
More information about the Zope-Checkins
mailing list