def execute (cmd, timeout = 0):
if timeout == 0:
timeout = win32event.INFINITE
info = win32process.CreateProcess(None, cmd, None, None, 0, 0, None, None, win32process.STARTUPINFO())
subprocess = info [0]
rc = win32event.WaitForSingleObject (subprocess, timeout)
if rc == win32event.WAIT_FAILED:
return -1
if rc == win32event.WAIT_TIMEOUT:
try:
win32process.TerminateProcess (subprocess, 0)
except pywintypes.error:
return -3
return -2
if rc == win32event.WAIT_OBJECT_0:
return win32process.GetExitCodeProcess(subprocess)
python类WAIT_OBJECT_0的实例源码
def test(fn):
print "The main thread is %d" % (win32api.GetCurrentThreadId())
GIT = CreateGIT()
interp = win32com.client.Dispatch("Python.Interpreter")
cookie = GIT.RegisterInterfaceInGlobal(interp._oleobj_, pythoncom.IID_IDispatch)
events = fn(4, cookie)
numFinished = 0
while 1:
try:
rc = win32event.MsgWaitForMultipleObjects(events, 0, 2000, win32event.QS_ALLINPUT)
if rc >= win32event.WAIT_OBJECT_0 and rc < win32event.WAIT_OBJECT_0+len(events):
numFinished = numFinished + 1
if numFinished >= len(events):
break
elif rc==win32event.WAIT_OBJECT_0 + len(events): # a message
# This is critical - whole apartment model demo will hang.
pythoncom.PumpWaitingMessages()
else: # Timeout
print "Waiting for thread to stop with interfaces=%d, gateways=%d" % (pythoncom._GetInterfaceCount(), pythoncom._GetGatewayCount())
except KeyboardInterrupt:
break
GIT.RevokeInterfaceFromGlobal(cookie)
del interp
del GIT
def WaitWhileProcessingMessages(event, timeout = 2):
start = time.clock()
while True:
# Wake 4 times a second - we can't just specify the
# full timeout here, as then it would reset for every
# message we process.
rc = win32event.MsgWaitForMultipleObjects( (event,), 0,
250,
win32event.QS_ALLEVENTS)
if rc == win32event.WAIT_OBJECT_0:
# event signalled - stop now!
return True
if (time.clock() - start) > timeout:
# Timeout expired.
return False
# must be a message.
pythoncom.PumpWaitingMessages()
def timeout_execute (cmd, timeout = 0):
if timeout == 0:
timeout = win32event.INFINITE
info = win32process.CreateProcess(None, cmd, None, None, 0, 0, None, None, win32process.STARTUPINFO())
subprocess = info [0]
rc = win32event.WaitForSingleObject (subprocess, timeout)
if rc == win32event.WAIT_FAILED:
return -1
if rc == win32event.WAIT_TIMEOUT:
try:
win32process.TerminateProcess (subprocess, 0)
except pywintypes.error:
return -3
return -2
if rc == win32event.WAIT_OBJECT_0:
return win32process.GetExitCodeProcess(subprocess)
def test(fn):
print "The main thread is %d" % (win32api.GetCurrentThreadId())
GIT = CreateGIT()
interp = win32com.client.Dispatch("Python.Interpreter")
cookie = GIT.RegisterInterfaceInGlobal(interp._oleobj_, pythoncom.IID_IDispatch)
events = fn(4, cookie)
numFinished = 0
while 1:
try:
rc = win32event.MsgWaitForMultipleObjects(events, 0, 2000, win32event.QS_ALLINPUT)
if rc >= win32event.WAIT_OBJECT_0 and rc < win32event.WAIT_OBJECT_0+len(events):
numFinished = numFinished + 1
if numFinished >= len(events):
break
elif rc==win32event.WAIT_OBJECT_0 + len(events): # a message
# This is critical - whole apartment model demo will hang.
pythoncom.PumpWaitingMessages()
else: # Timeout
print "Waiting for thread to stop with interfaces=%d, gateways=%d" % (pythoncom._GetInterfaceCount(), pythoncom._GetGatewayCount())
except KeyboardInterrupt:
break
GIT.RevokeInterfaceFromGlobal(cookie)
del interp
del GIT
def WaitWhileProcessingMessages(event, timeout = 2):
start = time.clock()
while True:
# Wake 4 times a second - we can't just specify the
# full timeout here, as then it would reset for every
# message we process.
rc = win32event.MsgWaitForMultipleObjects( (event,), 0,
250,
win32event.QS_ALLEVENTS)
if rc == win32event.WAIT_OBJECT_0:
# event signalled - stop now!
return True
if (time.clock() - start) > timeout:
# Timeout expired.
return False
# must be a message.
pythoncom.PumpWaitingMessages()
def run(cmd, mSec=None, stdin=None, stdout=None, stderr=None, **kw):
"""
Run cmd as a child process and return exit code.
mSec: terminate cmd after specified number of milliseconds
stdin, stdout, stderr:
file objects for child I/O (use hStdin etc. to attach
handles instead of files); default is caller's stdin,
stdout & stderr;
kw: see Process.__init__ for more keyword options
"""
if stdin is not None:
kw['hStdin'] = msvcrt.get_osfhandle(stdin.fileno())
if stdout is not None:
kw['hStdout'] = msvcrt.get_osfhandle(stdout.fileno())
if stderr is not None:
kw['hStderr'] = msvcrt.get_osfhandle(stderr.fileno())
child = Process(cmd, **kw)
if child.wait(mSec) != win32event.WAIT_OBJECT_0:
child.kill()
raise WindowsError('process timeout exceeded')
return child.exitCode()
def Run(self):
while 1:
handles = [self.stopEvent, self.adminEvent]
if self.watchEvent is not None:
handles.append(self.watchEvent)
rc = win32event.WaitForMultipleObjects(handles, 0, win32event.INFINITE)
if rc == win32event.WAIT_OBJECT_0:
break
elif rc == win32event.WAIT_OBJECT_0+1:
self.RefreshEvent()
else:
win32api.PostMessage(self.hwnd, MSG_CHECK_EXTERNAL_FILE, 0, 0)
try:
# If the directory has been removed underneath us, we get this error.
win32api.FindNextChangeNotification(self.watchEvent)
except win32api.error, exc:
print "Can not watch file", self.doc.GetPathName(), "for changes -", exc.strerror
break
# close a circular reference
self.doc = None
if self.watchEvent:
win32api.FindCloseChangeNotification(self.watchEvent)
def test(fn):
print "The main thread is %d" % (win32api.GetCurrentThreadId())
GIT = CreateGIT()
interp = win32com.client.Dispatch("Python.Interpreter")
cookie = GIT.RegisterInterfaceInGlobal(interp._oleobj_, pythoncom.IID_IDispatch)
events = fn(4, cookie)
numFinished = 0
while 1:
try:
rc = win32event.MsgWaitForMultipleObjects(events, 0, 2000, win32event.QS_ALLINPUT)
if rc >= win32event.WAIT_OBJECT_0 and rc < win32event.WAIT_OBJECT_0+len(events):
numFinished = numFinished + 1
if numFinished >= len(events):
break
elif rc==win32event.WAIT_OBJECT_0 + len(events): # a message
# This is critical - whole apartment model demo will hang.
pythoncom.PumpWaitingMessages()
else: # Timeout
print "Waiting for thread to stop with interfaces=%d, gateways=%d" % (pythoncom._GetInterfaceCount(), pythoncom._GetGatewayCount())
except KeyboardInterrupt:
break
GIT.RevokeInterfaceFromGlobal(cookie)
del interp
del GIT
def WaitWhileProcessingMessages(event, timeout = 2):
start = time.clock()
while True:
# Wake 4 times a second - we can't just specify the
# full timeout here, as then it would reset for every
# message we process.
rc = win32event.MsgWaitForMultipleObjects( (event,), 0,
250,
win32event.QS_ALLEVENTS)
if rc == win32event.WAIT_OBJECT_0:
# event signalled - stop now!
return True
if (time.clock() - start) > timeout:
# Timeout expired.
return False
# must be a message.
pythoncom.PumpWaitingMessages()
def Run(self):
while 1:
handles = [self.stopEvent, self.adminEvent]
if self.watchEvent is not None:
handles.append(self.watchEvent)
rc = win32event.WaitForMultipleObjects(handles, 0, win32event.INFINITE)
if rc == win32event.WAIT_OBJECT_0:
break
elif rc == win32event.WAIT_OBJECT_0+1:
self.RefreshEvent()
else:
win32api.PostMessage(self.hwnd, MSG_CHECK_EXTERNAL_FILE, 0, 0)
try:
# If the directory has been removed underneath us, we get this error.
win32api.FindNextChangeNotification(self.watchEvent)
except win32api.error as exc:
print("Can not watch file", self.doc.GetPathName(), "for changes -", exc.strerror)
break
# close a circular reference
self.doc = None
if self.watchEvent:
win32api.FindCloseChangeNotification(self.watchEvent)
def CollectorThread(stopEvent, file):
win32trace.InitRead()
handle = win32trace.GetHandle()
# Run this thread at a lower priority to the main message-loop (and printing output)
# thread can keep up
import win32process
win32process.SetThreadPriority(win32api.GetCurrentThread(), win32process.THREAD_PRIORITY_BELOW_NORMAL)
try:
while 1:
rc = win32event.WaitForMultipleObjects((handle, stopEvent), 0, win32event.INFINITE)
if rc == win32event.WAIT_OBJECT_0:
# About the only char we can't live with is \0!
file.write(win32trace.read().replace("\0", "<null>"))
else:
# Stop event
break
finally:
win32trace.TermRead()
print("Thread dieing")
def run(cmd, mSec=None, stdin=None, stdout=None, stderr=None, **kw):
"""
Run cmd as a child process and return exit code.
mSec: terminate cmd after specified number of milliseconds
stdin, stdout, stderr:
file objects for child I/O (use hStdin etc. to attach
handles instead of files); default is caller's stdin,
stdout & stderr;
kw: see Process.__init__ for more keyword options
"""
if stdin is not None:
kw['hStdin'] = msvcrt.get_osfhandle(stdin.fileno())
if stdout is not None:
kw['hStdout'] = msvcrt.get_osfhandle(stdout.fileno())
if stderr is not None:
kw['hStderr'] = msvcrt.get_osfhandle(stderr.fileno())
child = Process(cmd, **kw)
if child.wait(mSec) != win32event.WAIT_OBJECT_0:
child.kill()
raise WindowsError('process timeout exceeded')
return child.exitCode()
def test(fn):
print("The main thread is %d" % (win32api.GetCurrentThreadId()))
GIT = CreateGIT()
interp = win32com.client.Dispatch("Python.Interpreter")
cookie = GIT.RegisterInterfaceInGlobal(interp._oleobj_, pythoncom.IID_IDispatch)
events = fn(4, cookie)
numFinished = 0
while 1:
try:
rc = win32event.MsgWaitForMultipleObjects(events, 0, 2000, win32event.QS_ALLINPUT)
if rc >= win32event.WAIT_OBJECT_0 and rc < win32event.WAIT_OBJECT_0+len(events):
numFinished = numFinished + 1
if numFinished >= len(events):
break
elif rc==win32event.WAIT_OBJECT_0 + len(events): # a message
# This is critical - whole apartment model demo will hang.
pythoncom.PumpWaitingMessages()
else: # Timeout
print("Waiting for thread to stop with interfaces=%d, gateways=%d" % (pythoncom._GetInterfaceCount(), pythoncom._GetGatewayCount()))
except KeyboardInterrupt:
break
GIT.RevokeInterfaceFromGlobal(cookie)
del interp
del GIT
def WaitWhileProcessingMessages(event, timeout = 2):
start = time.clock()
while True:
# Wake 4 times a second - we can't just specify the
# full timeout here, as then it would reset for every
# message we process.
rc = win32event.MsgWaitForMultipleObjects( (event,), 0,
250,
win32event.QS_ALLEVENTS)
if rc == win32event.WAIT_OBJECT_0:
# event signalled - stop now!
return True
if (time.clock() - start) > timeout:
# Timeout expired.
return False
# must be a message.
pythoncom.PumpWaitingMessages()
def eof(self):
### should be calling file.eof() here instead of file.close(), there
### may be data in the pipe or buffer after the process exits
if sys.platform == "win32":
r = win32event.WaitForMultipleObjects(self.wait_for, 1, 0)
if r == win32event.WAIT_OBJECT_0:
self.file.close()
self.file = None
return win32process.GetExitCodeProcess(self.child_pid)
return None
if self.thread and self.thread.isAlive():
return None
pid, status = os.waitpid(self.child_pid, os.WNOHANG)
if pid:
self.file.close()
self.file = None
return status
return None
def signalCheckerThread(self):
while not self.shutdown_requested:
handles = [self.admin_event_handle]
signums = [None]
for signum, handle in self.event_handles.items():
signums.append(signum)
handles.append(handle)
rc = win32event.WaitForMultipleObjects(handles, False,
win32event.INFINITE)
logger.debug("signalCheckerThread awake with %s" % rc)
signum = signums[rc - win32event.WAIT_OBJECT_0]
if signum is None:
# Admin event - either shutdown, or new event object created.
pass
else:
logger.debug("signalCheckerThread calling %s" % signum)
self.signalHandler(signum, None)
logger.debug("signalCheckerThread back")
logger.debug("signalCheckerThread stopped")
def pipe(bufsize=8192):
"""Creates overlapped (asynchronous) pipe.
"""
name = r'\\.\pipe\pycos-pipe-%d-%d' % (os.getpid(), next(_pipe_id))
openmode = (win32pipe.PIPE_ACCESS_INBOUND | win32file.FILE_FLAG_OVERLAPPED |
FILE_FLAG_FIRST_PIPE_INSTANCE)
pipemode = (win32pipe.PIPE_TYPE_BYTE | win32pipe.PIPE_READMODE_BYTE)
rh = wh = None
try:
rh = win32pipe.CreateNamedPipe(
name, openmode, pipemode, 1, bufsize, bufsize,
win32pipe.NMPWAIT_USE_DEFAULT_WAIT, None)
wh = win32file.CreateFile(
name, win32file.GENERIC_WRITE | winnt.FILE_READ_ATTRIBUTES, 0, None,
win32file.OPEN_EXISTING, win32file.FILE_FLAG_OVERLAPPED, None)
overlapped = pywintypes.OVERLAPPED()
# 'yield' can't be used in constructor so use sync wait
# (in this case it is should be okay)
overlapped.hEvent = win32event.CreateEvent(None, 0, 0, None)
rc = win32pipe.ConnectNamedPipe(rh, overlapped)
if rc == winerror.ERROR_PIPE_CONNECTED:
win32event.SetEvent(overlapped.hEvent)
rc = win32event.WaitForSingleObject(overlapped.hEvent, 1000)
overlapped = None
if rc != win32event.WAIT_OBJECT_0:
pycos.logger.warning('connect failed: %s' % rc)
raise Exception(rc)
return (rh, wh)
except:
if rh is not None:
win32file.CloseHandle(rh)
if wh is not None:
win32file.CloseHandle(wh)
raise
def pipe(bufsize=8192):
"""Creates overlapped (asynchronous) pipe.
"""
name = r'\\.\pipe\pycos-pipe-%d-%d' % (os.getpid(), next(_pipe_id))
openmode = (win32pipe.PIPE_ACCESS_INBOUND | win32file.FILE_FLAG_OVERLAPPED |
FILE_FLAG_FIRST_PIPE_INSTANCE)
pipemode = (win32pipe.PIPE_TYPE_BYTE | win32pipe.PIPE_READMODE_BYTE)
rh = wh = None
try:
rh = win32pipe.CreateNamedPipe(
name, openmode, pipemode, 1, bufsize, bufsize,
win32pipe.NMPWAIT_USE_DEFAULT_WAIT, None)
wh = win32file.CreateFile(
name, win32file.GENERIC_WRITE | winnt.FILE_READ_ATTRIBUTES, 0, None,
win32file.OPEN_EXISTING, win32file.FILE_FLAG_OVERLAPPED, None)
overlapped = pywintypes.OVERLAPPED()
# 'yield' can't be used in constructor so use sync wait
# (in this case it is should be okay)
overlapped.hEvent = win32event.CreateEvent(None, 0, 0, None)
rc = win32pipe.ConnectNamedPipe(rh, overlapped)
if rc == winerror.ERROR_PIPE_CONNECTED:
win32event.SetEvent(overlapped.hEvent)
rc = win32event.WaitForSingleObject(overlapped.hEvent, 1000)
overlapped = None
if rc != win32event.WAIT_OBJECT_0:
pycos.logger.warning('connect failed: %s' % rc)
raise Exception(rc)
return (rh, wh)
except:
if rh is not None:
win32file.CloseHandle(rh)
if wh is not None:
win32file.CloseHandle(wh)
raise
def notifyOnExit(self, processHandle, processTransport):
processHandleKey = self.phandleToPhandleKey[processHandle]
# If there are available threads, use one of them
if len(self.availableThreads) > 0:
wfmoThread = self.availableThreads[0]
self.threadToNumProcessHandles[wfmoThread] += 1
self.phandleKeyToThreadHandle[processHandleKey] = wfmoThread
# Update used/available thread lists
if self.threadToNumProcessHandles[wfmoThread] == 63:
self.usedThreads.append(wfmoThread)
self.availableThreads.remove(wfmoThread)
# Make sure the message window has been created so
# we can send messages to the thread.
if self.threadToMsgWindowCreated[wfmoThread] is False:
val = WaitForSingleObject(self.threadToMsgWindowCreationEvent[wfmoThread], INFINITE)
if val != WAIT_OBJECT_0:
raise RuntimeError("WaitForSingleObject returned %d. It should only return %d" % (val, WAIT_OBJECT_0))
# Notify the thread that it should wait on the process handle.
if win32api.PostMessage(
self.threadToMsgWindow[wfmoThread],
WM_NEW_PHANDLE, # message
processHandleKey, # wParam
0 # lParam
) == 0:
raise Exception("Failed to post thread message!")
else:
# Create a new thread and wait on the proc handle
wfmoThread = threading.Thread(
target=self.doWaitForProcessExit,
args=(processHandleKey,),
name="iocpreactor.process_waiter.ProcessWaiter.waitForProcessExit pid=%d" % self.realPid)
# Create a window creation event that will be triggered from the thread
self.threadToMsgWindowCreationEvent[wfmoThread] = CreateEvent(None, 0, 0, None)
self.threadToMsgWindowCreated[wfmoThread] = False
self.threadToNumProcessHandles[wfmoThread] = 1
self.availableThreads.append(wfmoThread)
self.phandleKeyToThreadHandle[processHandleKey] = wfmoThread
wfmoThread.start()
def processEnded(self, processHandle, processHandleKey):
wfmoThread = self.phandleKeyToThreadHandle[processHandleKey]
processTransport = self.phandleToTransport[processHandle]
self.threadToNumEnded[wfmoThread] += 1
# Decrement proc handle count for thread
self.threadToNumProcessHandles[wfmoThread] -= 1
# If we go from 63 to 62 phandles for the thread, mark it available.
if self.threadToNumProcessHandles[wfmoThread] == 62:
self.availableThreads.append(wfmoThread)
self.usedThreads.remove(wfmoThread)
# If we go to 0 phandles, end the thread
elif self.threadToNumProcessHandles[wfmoThread] == 0:
# Mark thread as unavailable
self.availableThreads.remove(wfmoThread)
# Notify the thread that it should exit.
if not self.threadToMsgWindowCreated[wfmoThread]:
val = WaitForSingleObject(self.threadToMsgWindowCreationEvent[wfmoThread], INFINITE)
if val != WAIT_OBJECT_0:
raise RuntimeError("WaitForSingleObject returned %d. It should only return %d" % (val, WAIT_OBJECT_0))
# Notify the thread that it should wait on the process handle.
win32api.PostMessage(
self.threadToMsgWindow[wfmoThread], # thread id
WM_CLOSE_THREAD, # message
0, # wParam
0 # lParam
)
# Cleanup thread resources
del self.threadToNumProcessHandles[wfmoThread]
del self.threadToMsgWindowCreated[wfmoThread]
#del self.wfmoThread
# Cleanup process handle resources
del self.needWaiting[processHandleKey]
del self.phandleToTransport[processHandle]
# Call the transport's processEnded method
processTransport.processEnded()
def checkWork(self):
if win32event.WaitForSingleObject(self.proc.hProcess, 0) != win32event.WAIT_OBJECT_0:
return 0
exitCode = win32process.GetExitCodeProcess(self.proc.hProcess)
if exitCode == 0:
err = error.ProcessDone(exitCode)
else:
err = error.ProcessTerminated(exitCode)
self.deactivate()
self.proc.protocol.processEnded(failure.Failure(err))
return 0
def _DoTestMarshal(self, fn, bCoWait = 0):
#print "The main thread is %d" % (win32api.GetCurrentThreadId())
threads, events = fn(2)
numFinished = 0
while 1:
try:
if bCoWait:
rc = pythoncom.CoWaitForMultipleHandles(0, 2000, events)
else:
# Specifying "bWaitAll" here will wait for messages *and* all events
# (which is pretty useless)
rc = win32event.MsgWaitForMultipleObjects(events, 0, 2000, win32event.QS_ALLINPUT)
if rc >= win32event.WAIT_OBJECT_0 and rc < win32event.WAIT_OBJECT_0+len(events):
numFinished = numFinished + 1
if numFinished >= len(events):
break
elif rc==win32event.WAIT_OBJECT_0 + len(events): # a message
# This is critical - whole apartment model demo will hang.
pythoncom.PumpWaitingMessages()
else: # Timeout
print "Waiting for thread to stop with interfaces=%d, gateways=%d" % (pythoncom._GetInterfaceCount(), pythoncom._GetGatewayCount())
except KeyboardInterrupt:
break
for t in threads:
t.join(2)
self.failIf(t.isAlive(), "thread failed to stop!?")
threads = None # threads hold references to args
# Seems to be a leak here I can't locate :(
#self.failUnlessEqual(pythoncom._GetInterfaceCount(), 0)
#self.failUnlessEqual(pythoncom._GetGatewayCount(), 0)
def TestExplorerEvents():
iexplore = win32com.client.DispatchWithEvents(
"InternetExplorer.Application", ExplorerEvents)
thread = win32api.GetCurrentThreadId()
print 'TestExplorerEvents created IE object on thread %d'%thread
iexplore.Visible = 1
try:
iexplore.Navigate(win32api.GetFullPathName('..\\readme.htm'))
except pythoncom.com_error, details:
print "Warning - could not open the test HTML file", details
# In this free-threaded example, we can simply wait until an event has
# been set - we will give it 2 seconds before giving up.
rc = win32event.WaitForSingleObject(iexplore.event, 2000)
if rc != win32event.WAIT_OBJECT_0:
print "Document load event FAILED to fire!!!"
iexplore.Quit()
# Now we can do the same thing to wait for exit!
# Although Quit generates events, in this free-threaded world we
# do *not* need to run any message pumps.
rc = win32event.WaitForSingleObject(iexplore.event, 2000)
if rc != win32event.WAIT_OBJECT_0:
print "OnQuit event FAILED to fire!!!"
iexplore = None
print "Finished the IE event sample!"
def _DoTestMarshal(self, fn, bCoWait = 0):
#print "The main thread is %d" % (win32api.GetCurrentThreadId())
threads, events = fn(2)
numFinished = 0
while 1:
try:
if bCoWait:
rc = pythoncom.CoWaitForMultipleHandles(0, 2000, events)
else:
# Specifying "bWaitAll" here will wait for messages *and* all events
# (which is pretty useless)
rc = win32event.MsgWaitForMultipleObjects(events, 0, 2000, win32event.QS_ALLINPUT)
if rc >= win32event.WAIT_OBJECT_0 and rc < win32event.WAIT_OBJECT_0+len(events):
numFinished = numFinished + 1
if numFinished >= len(events):
break
elif rc==win32event.WAIT_OBJECT_0 + len(events): # a message
# This is critical - whole apartment model demo will hang.
pythoncom.PumpWaitingMessages()
else: # Timeout
print "Waiting for thread to stop with interfaces=%d, gateways=%d" % (pythoncom._GetInterfaceCount(), pythoncom._GetGatewayCount())
except KeyboardInterrupt:
break
for t in threads:
t.join(2)
self.failIf(t.isAlive(), "thread failed to stop!?")
threads = None # threads hold references to args
# Seems to be a leak here I can't locate :(
#self.failUnlessEqual(pythoncom._GetInterfaceCount(), 0)
#self.failUnlessEqual(pythoncom._GetGatewayCount(), 0)
def TestExplorerEvents():
iexplore = win32com.client.DispatchWithEvents(
"InternetExplorer.Application", ExplorerEvents)
thread = win32api.GetCurrentThreadId()
print 'TestExplorerEvents created IE object on thread %d'%thread
iexplore.Visible = 1
try:
iexplore.Navigate(win32api.GetFullPathName('..\\readme.htm'))
except pythoncom.com_error, details:
print "Warning - could not open the test HTML file", details
# In this free-threaded example, we can simply wait until an event has
# been set - we will give it 2 seconds before giving up.
rc = win32event.WaitForSingleObject(iexplore.event, 2000)
if rc != win32event.WAIT_OBJECT_0:
print "Document load event FAILED to fire!!!"
iexplore.Quit()
# Now we can do the same thing to wait for exit!
# Although Quit generates events, in this free-threaded world we
# do *not* need to run any message pumps.
rc = win32event.WaitForSingleObject(iexplore.event, 2000)
if rc != win32event.WAIT_OBJECT_0:
print "OnQuit event FAILED to fire!!!"
iexplore = None
print "Finished the IE event sample!"
def SvcDoRun(self):
# Redirect stdout and stderr to prevent "IOError: [Errno 9]
# Bad file descriptor". Windows services don't have functional
# output streams.
sys.stdout = sys.stderr = open('nul', 'w')
# Write a 'started' event to the event log...
win32evtlogutil.ReportEvent(self._svc_display_name_,
servicemanager.PYS_SERVICE_STARTED,
0, # category
servicemanager.EVENTLOG_INFORMATION_TYPE,
(self._svc_name_, ''))
print("Begin: %s" % (self._svc_display_name_))
hostport = ':8888'
print('Starting py.execnet SocketServer on %s' % hostport)
serversock = socketserver.bind_and_listen(hostport)
thread = threading.Thread(
target=socketserver.startserver,
args=(serversock,),
kwargs={'loop': True})
thread.setDaemon(True)
thread.start()
# wait to be stopped or self.WAIT_TIME to pass
while True:
result = win32event.WaitForSingleObject(
self.hWaitStop, self.WAIT_TIME)
if result == win32event.WAIT_OBJECT_0:
break
# write a 'stopped' event to the event log.
win32evtlogutil.ReportEvent(self._svc_display_name_,
servicemanager.PYS_SERVICE_STOPPED,
0, # category
servicemanager.EVENTLOG_INFORMATION_TYPE,
(self._svc_name_, ''))
print("End: %s" % appname)
def notifyOnExit(self, processHandle, processTransport):
processHandleKey = self.phandleToPhandleKey[processHandle]
# If there are available threads, use one of them
if len(self.availableThreads) > 0:
wfmoThread = self.availableThreads[0]
self.threadToNumProcessHandles[wfmoThread] += 1
self.phandleKeyToThreadHandle[processHandleKey] = wfmoThread
# Update used/available thread lists
if self.threadToNumProcessHandles[wfmoThread] == 63:
self.usedThreads.append(wfmoThread)
self.availableThreads.remove(wfmoThread)
# Make sure the message window has been created so
# we can send messages to the thread.
if self.threadToMsgWindowCreated[wfmoThread] is False:
val = WaitForSingleObject(self.threadToMsgWindowCreationEvent[wfmoThread], INFINITE)
if val != WAIT_OBJECT_0:
raise RuntimeError("WaitForSingleObject returned %d. It should only return %d" % (val, WAIT_OBJECT_0))
# Notify the thread that it should wait on the process handle.
if win32api.PostMessage(
self.threadToMsgWindow[wfmoThread],
WM_NEW_PHANDLE, # message
processHandleKey, # wParam
0 # lParam
) == 0:
raise Exception("Failed to post thread message!")
else:
# Create a new thread and wait on the proc handle
wfmoThread = threading.Thread(
target=self.doWaitForProcessExit,
args=(processHandleKey,),
name="iocpreactor.process_waiter.ProcessWaiter.waitForProcessExit pid=%d" % self.realPid)
# Create a window creation event that will be triggered from the thread
self.threadToMsgWindowCreationEvent[wfmoThread] = CreateEvent(None, 0, 0, None)
self.threadToMsgWindowCreated[wfmoThread] = False
self.threadToNumProcessHandles[wfmoThread] = 1
self.availableThreads.append(wfmoThread)
self.phandleKeyToThreadHandle[processHandleKey] = wfmoThread
wfmoThread.start()
def processEnded(self, processHandle, processHandleKey):
wfmoThread = self.phandleKeyToThreadHandle[processHandleKey]
processTransport = self.phandleToTransport[processHandle]
self.threadToNumEnded[wfmoThread] += 1
# Decrement proc handle count for thread
self.threadToNumProcessHandles[wfmoThread] -= 1
# If we go from 63 to 62 phandles for the thread, mark it available.
if self.threadToNumProcessHandles[wfmoThread] == 62:
self.availableThreads.append(wfmoThread)
self.usedThreads.remove(wfmoThread)
# If we go to 0 phandles, end the thread
elif self.threadToNumProcessHandles[wfmoThread] == 0:
# Mark thread as unavailable
self.availableThreads.remove(wfmoThread)
# Notify the thread that it should exit.
if not self.threadToMsgWindowCreated[wfmoThread]:
val = WaitForSingleObject(self.threadToMsgWindowCreationEvent[wfmoThread], INFINITE)
if val != WAIT_OBJECT_0:
raise RuntimeError("WaitForSingleObject returned %d. It should only return %d" % (val, WAIT_OBJECT_0))
# Notify the thread that it should wait on the process handle.
win32api.PostMessage(
self.threadToMsgWindow[wfmoThread], # thread id
WM_CLOSE_THREAD, # message
0, # wParam
0 # lParam
)
# Cleanup thread resources
del self.threadToNumProcessHandles[wfmoThread]
del self.threadToMsgWindowCreated[wfmoThread]
#del self.wfmoThread
# Cleanup process handle resources
del self.needWaiting[processHandleKey]
del self.phandleToTransport[processHandle]
# Call the transport's processEnded method
processTransport.processEnded()
def checkWork(self):
if win32event.WaitForSingleObject(self.proc.hProcess, 0) != win32event.WAIT_OBJECT_0:
return 0
exitCode = win32process.GetExitCodeProcess(self.proc.hProcess)
if exitCode == 0:
err = error.ProcessDone(exitCode)
else:
err = error.ProcessTerminated(exitCode)
self.deactivate()
self.proc.protocol.processEnded(failure.Failure(err))
return 0