# cmdserver.py # Demo code that is not Pythonwin related, but too good to throw away... import win32api import sys from pywin.framework import winout import _thread, sys import traceback class ThreadWriter: "Assign an instance to sys.stdout for per-thread printing objects - Courtesy Guido!" def __init__(self): "Constructor -- initialize the table of writers" self.writers = {} self.origStdOut = None def register(self, writer): "Register the writer for the current thread" self.writers[_thread.get_ident()] = writer if self.origStdOut is None: self.origStdOut = sys.stdout sys.stdout = self def unregister(self): "Remove the writer for the current thread, if any" try: del self.writers[_thread.get_ident()] except KeyError: pass if len(self.writers)==0: sys.stdout = self.origStdOut self.origStdOut = None def getwriter(self): "Return the current thread's writer, default sys.stdout" try: return self.writers[_thread.get_ident()] except KeyError: return self.origStdOut def write(self, str): "Write to the current thread's writer, default sys.stdout" self.getwriter().write(str) def Test(): num=1 while num<1000: print('Hello there no ' + str(num)) win32api.Sleep(50) num = num + 1 class flags: SERVER_BEST = 0 SERVER_IMMEDIATE = 1 SERVER_THREAD = 2 SERVER_PROCESS = 3 def StartServer( cmd, title=None, bCloseOnEnd=0, serverFlags = flags.SERVER_BEST ): out = winout.WindowOutput( title, None, winout.flags.WQ_IDLE ) if not title: title=cmd out.Create(title) # ServerThread((out, cmd, title, bCloseOnEnd)) # out = sys.stdout _thread.start_new_thread( ServerThread, (out, cmd, title, bCloseOnEnd) ) def ServerThread(myout, cmd, title, bCloseOnEnd): try: writer.register(myout) print('Executing "%s"\n' % cmd) bOK = 1 try: import __main__ exec (cmd+'\n', __main__.__dict__) except: bOK = 0 if bOK: print("Command terminated without errors.") else: t, v, tb = sys.exc_info() print(t, ': ', v) traceback.print_tb(tb) tb = None # prevent a cycle print("Command terminated with an unhandled exception") writer.unregister() if bOK and bCloseOnEnd: myout.frame.DestroyWindow() # Unhandled exception of any kind in a thread kills the gui! except: t, v, tb = sys.exc_info() print(t, ': ', v) traceback.print_tb(tb) tb = None print("Thread failed") # assist for reloading (when debugging) - use only 1 tracer object, # else a large chain of tracer objects will exist. #try: # writer #except NameError: # writer=ThreadWriter() if __name__=='__main__': import demoutils demoutils.NotAScript()