def __init__(self, dParams): PlatformBase.__init__(self, dParams) # # Since the code runs on all platforms, we have to do a lot of # importing here instead of at the top of the file where it's normally located. # from win32com import universal from win32com.client import gencache, DispatchBaseClass from win32com.client import constants, getevents import win32com import pythoncom import win32api import winerror from win32con import DUPLICATE_SAME_ACCESS from win32api import GetCurrentThread, GetCurrentThreadId, DuplicateHandle, GetCurrentProcess import threading self.winerror = winerror pid = GetCurrentProcess() self.tid = GetCurrentThreadId() handle = DuplicateHandle(pid, GetCurrentThread(), pid, 0, 0, DUPLICATE_SAME_ACCESS) self.handles = [] self.handles.append(handle) # Hack the COM dispatcher base class so we can modify method and # attribute names to match those in xpcom. if _g_dCOMForward['setattr'] is None: _g_dCOMForward['getattr'] = DispatchBaseClass.__dict__[ '__getattr__'] _g_dCOMForward['setattr'] = DispatchBaseClass.__dict__[ '__setattr__'] setattr(DispatchBaseClass, '__getattr__', _CustomGetAttr) setattr(DispatchBaseClass, '__setattr__', _CustomSetAttr) # Hack the exception base class so the users doesn't need to check for # XPCOM or COM and do different things. ## @todo # # Make sure the gencache is correct (we don't quite follow the COM # versioning rules). # self.flushGenPyCache(win32com.client.gencache) win32com.client.gencache.EnsureDispatch('VirtualBox.Session') win32com.client.gencache.EnsureDispatch('VirtualBox.VirtualBox') win32com.client.gencache.EnsureDispatch('VirtualBox.VirtualBoxClient') self.oIntCv = threading.Condition() self.fInterrupted = False _ = dParams
def get_text_from_focused_control(): try: activeWinPtr = GetForegroundWindow() activeThreadId, _ = GetWindowThreadProcessId(activeWinPtr) currentThreadId = GetCurrentThreadId() if activeThreadId != currentThreadId: AttachThreadInput(activeThreadId, currentThreadId, True) activeCtrlId = GetFocus() return GetText(activeCtrlId) except Exception: print("HUHU") return ""
def WorkerThread(object): # First step - initialize COM CoInitializeEx(COINIT_MULTITHREADED) this_id = GetCurrentThreadId() that_id = object.GetCurrentThreadId() message = "Thread is %d, and object is on thread %d" % \ (this_id, that_id) print message # Be a good citizen and finalize COM, but # first remove our object references. object = None CoUninitialize()
def WorkerThread(object_stream): # First step - initialize COM CoInitialize() # Single-threaded. # Unmarshal the IDispatch object. object = CoGetInterfaceAndReleaseStream( object_stream, IID_IDispatch) # The object we get back is a PyIDispatch, rather # than a friendly Dispatch instance, so we convert # to a usable object. object = Dispatch(object) this_id = GetCurrentThreadId() that_id = object.GetCurrentThreadId() message = "Thread is %d, and object is on thread %d" % \ (this_id, that_id) print message # Be a good citizen and finalize COM, but # first remove our object references. object = None CoUninitialize()
def Demo(prog_id): # First create the object object = Dispatch(prog_id) print "Thread", GetCurrentThreadId(), "creating object" created_id = object.GetCreatedThreadId() print "Object reports it was created on thread", created_id # Now create the threads, remembering the handles. handles = [] for i in range(3): # Multi-threaded - just pass the objects directly to the thread. args = (object, ) handle, id = beginthreadex(None, 0, WorkerThread, args, 0) handles.append(handle) # Now we have all the threads running, wait for them to terminate. # No need for message pump, so we can simply wait for all objects # in one call. rc = WaitForMultipleObjects(handles, 1, 5000) if rc == WAIT_ABANDONED: print "Gave up waiting for the threads to finish!" print "Demo of", prog_id, "finished."
def waitForEvents(self, timeout): from win32api import GetCurrentThreadId from win32event import INFINITE from win32event import MsgWaitForMultipleObjects, \ QS_ALLINPUT, WAIT_TIMEOUT, WAIT_OBJECT_0 from pythoncom import PumpWaitingMessages import types if not isinstance(timeout, int): raise TypeError("The timeout argument is not an integer") if self.tid != GetCurrentThreadId(): raise Exception("wait for events from the same thread you inited!") if timeout < 0: cMsTimeout = INFINITE else: cMsTimeout = timeout rc = MsgWaitForMultipleObjects(self.handles, 0, cMsTimeout, QS_ALLINPUT) if WAIT_OBJECT_0 <= rc < WAIT_OBJECT_0 + len(self.handles): # is it possible? rc = 2 elif rc == WAIT_OBJECT_0 + len(self.handles): # Waiting messages PumpWaitingMessages() rc = 0 else: # Timeout rc = 1 # check for interruption self.oIntCv.acquire() if self.fInterrupted: self.fInterrupted = False rc = 1 self.oIntCv.release() return rc
def SetForegroundWindowInternal(hWnd): if not IsWindow(hWnd): return # relation time of SetForegroundWindow lock lockTimeOut = 0 hCurrWnd = GetForegroundWindow() dwThisTID = GetCurrentThreadId() dwCurrTID = GetWindowThreadProcessId(hCurrWnd, 0) # we need to bypass some limitations from Microsoft :) if dwThisTID != dwCurrTID: AttachThreadInput(dwThisTID, dwCurrTID, TRUE) SystemParametersInfo( SPI_SETFOREGROUNDLOCKTIMEOUT,0,SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE) AllowSetForegroundWindow(ASFW_ANY) SetForegroundWindow(hWnd) if dwThisTID != dwCurrTID: AttachThreadInput(dwThisTID, dwCurrTID, FALSE)
def Demo( prog_id ): # First create the object object = Dispatch(prog_id) print "Thread", GetCurrentThreadId(), "creating object" created_id = object.GetCreatedThreadId() print "Object reports it was created on thread", created_id # Now create the threads, remembering the handles. handles = [] for i in range(3): # As we are not allowed to pass the object directly between # apartments, we need to marshal it. object_stream = CoMarshalInterThreadInterfaceInStream( IID_IDispatch, object ) # Build an argument tuple for the thread. args = (object_stream,) handle, id = beginthreadex(None, 0, WorkerThread, args, 0) handles.append(handle) # Now we have all the threads running, wait for them to terminate. # also remember how many times we are asked to pump messages. num_pumps = 0 while handles: # A quirk in MsgWaitForMultipleObjects means we must wait # for each event one at at time rc = MsgWaitForMultipleObjects(handles, 0, 5000, QS_ALLINPUT) if rc >= WAIT_OBJECT_0 and rc < WAIT_OBJECT_0+len(handles): # A thread finished - remove its handle. del handles[rc-WAIT_OBJECT_0] elif rc==WAIT_OBJECT_0 + len(handles): # Waiting message num_pumps = num_pumps + 1 PumpWaitingMessages() else: print "Nothing seems to be happening", print "but I will keep waiting anyway..." print "Pumped messages", num_pumps, "times" print "Demo of", prog_id, "finished."
def __init__(self, params): from win32com import universal from win32com.client import gencache, DispatchBaseClass from win32com.client import constants, getevents import win32com import pythoncom import win32api from win32con import DUPLICATE_SAME_ACCESS from win32api import GetCurrentThread, GetCurrentThreadId, DuplicateHandle, GetCurrentProcess import threading pid = GetCurrentProcess() self.tid = GetCurrentThreadId() handle = DuplicateHandle(pid, GetCurrentThread(), pid, 0, 0, DUPLICATE_SAME_ACCESS) self.handles = [] self.handles.append(handle) _COMForward['getattr'] = DispatchBaseClass.__dict__['__getattr__'] DispatchBaseClass.__getattr__ = CustomGetAttr _COMForward['setattr'] = DispatchBaseClass.__dict__['__setattr__'] DispatchBaseClass.__setattr__ = CustomSetAttr win32com.client.gencache.EnsureDispatch('VirtualBox.Session') win32com.client.gencache.EnsureDispatch('VirtualBox.VirtualBox') self.oIntCv = threading.Condition() self.fInterrupted = False
def __init__(self, dParams): PlatformBase.__init__(self, dParams) # # Since the code runs on all platforms, we have to do a lot of # importing here instead of at the top of the file where it's normally located. # from win32com import universal from win32com.client import gencache, DispatchBaseClass from win32com.client import constants, getevents import win32com import pythoncom import win32api import winerror from win32con import DUPLICATE_SAME_ACCESS from win32api import GetCurrentThread, GetCurrentThreadId, DuplicateHandle, GetCurrentProcess import threading self.winerror = winerror # Setup client impersonation in COM calls. try: pythoncom.CoInitializeSecurity(None, None, None, pythoncom.RPC_C_AUTHN_LEVEL_DEFAULT, pythoncom.RPC_C_IMP_LEVEL_IMPERSONATE, None, pythoncom.EOAC_NONE, None) except: _, oXcpt, _ = sys.exc_info(); if isinstance(oXcpt, pythoncom.com_error) and self.xcptGetStatus(oXcpt) == -2147417831: # RPC_E_TOO_LATE print("Warning: CoInitializeSecurity was already called"); else: print("Warning: CoInitializeSecurity failed: ", oXctp); # Remember this thread ID and get its handle so we can wait on it in waitForEvents(). self.tid = GetCurrentThreadId() pid = GetCurrentProcess() self.aoHandles = [DuplicateHandle(pid, GetCurrentThread(), pid, 0, 0, DUPLICATE_SAME_ACCESS),]; # type: list[PyHANDLE] # Hack the COM dispatcher base class so we can modify method and # attribute names to match those in xpcom. if _g_dCOMForward['setattr'] is None: _g_dCOMForward['getattr'] = DispatchBaseClass.__dict__['__getattr__'] _g_dCOMForward['setattr'] = DispatchBaseClass.__dict__['__setattr__'] setattr(DispatchBaseClass, '__getattr__', _CustomGetAttr) setattr(DispatchBaseClass, '__setattr__', _CustomSetAttr) # Hack the exception base class so the users doesn't need to check for # XPCOM or COM and do different things. ## @todo # # Make sure the gencache is correct (we don't quite follow the COM # versioning rules). # self.flushGenPyCache(win32com.client.gencache) win32com.client.gencache.EnsureDispatch('VirtualBox.Session') win32com.client.gencache.EnsureDispatch('VirtualBox.VirtualBox') win32com.client.gencache.EnsureDispatch('VirtualBox.VirtualBoxClient') self.oClient = None ##< instance of client used to support lifetime of VBoxSDS self.oIntCv = threading.Condition() self.fInterrupted = False _ = dParams
def secondary_startup(node, cage, mode): cage_dir = os_path.join(cages_dir, cage) logs_dir = os_path.join(cage_dir, "logs") lib_dir = os_path.join(cage_dir, "lib") sys_path.insert(0, lib_dir) log_abbrevs = { 1: "ERR", 2: "MSG", 3: "WRN", 4: "LOG", 5: "INF", 6: "DBG", 7: "NSE" } log_encoding = "windows-1251" log_translate = b" \t " + bytes(range( 32, 256)) log_lock = Lock() log_yyyymmdd = None log_file = None # the following function will serve for all cage's logging def log(message, *, msg_level): nonlocal log_yyyymmdd, log_file line_time = time() line_yyyymmdd, line_hhmmss = strftime("%Y%m%d %H:%M:%S", localtime(line_time)).split(" ") log_line = "{0:s}.{1:02d} {2:s} [{3:s}] {4:s}".format( line_hhmmss, int(line_time * 100) % 100, log_abbrevs.get(msg_level, "???"), current_thread().name, message) with log_lock: if line_yyyymmdd != log_yyyymmdd: # rotate log file try: new_log_file_name = os_path.join( logs_dir, "{0:s}-{1:s}.log".format(cage, line_yyyymmdd)) new_log_file = fopen( new_log_file_name, os.O_WRONLY | os.O_CREAT | os.O_APPEND) except: pass # if rotation fails, previous log file will still be used else: try: close(log_file) except: pass # this also catches the attempt to close None log_file = new_log_file log_yyyymmdd = line_yyyymmdd if log_file is not None: if message: write( log_file, log_line.encode(log_encoding, "replace").translate(log_translate) + b"\n") if msg_level == 1: fsync(log_file) ################################### # create loader instance using initial default logging level pmnc = ModuleLoader(node, cage, cage_dir, log, "LOG", 2.0, 1.0) ################################### current_thread().name = "startup" if mode == "NORMAL": log("the cage is starting up", msg_level=2) elif mode == "FAILURE": log("the cage is restarting after a failure", msg_level=2) ################################### if win32_com: _main_thread_id = GetCurrentThreadId() def cage_thread_proc(): try: pmnc.startup.start() try: while not pmnc.startup.wait(3.0): pmnc.startup.maintenance() except: pmnc.log.error(exc_string()) # log and ignore finally: pmnc.startup.stop() finally: if win32_com: # release the main thread blocked in PumpMessages PostThreadMessage(_main_thread_id, WM_QUIT) cage_thread = HeavyThread(target=cage_thread_proc, name="cage") cage_thread.start() ################################### def termination_watchdog_proc(): try: while stdout.write("\n") > 0: stdout.flush() sleep(3.0) except: pass finally: pmnc.startup.exit() termination_watchdog = HeavyThread(target=termination_watchdog_proc, name="stdout") termination_watchdog.start() ################################### # wait for the cage thread to detect shutdown and terminate if win32_com: PumpMessages() # in the meanwhile become a message pump cage_thread.join() ################################### log("the cage has been properly shut down", msg_level=2) log("", msg_level=1) # force flush of a log file