from http.server import BaseHTTPRequestHandler, HTTPServer from pywinauto import win32defines, win32structures, win32functions import pdb import pywinauto import json import sys import ctypes import struct import os import select import zlib #Флаг отладки напрямую (не выполнять чтение буфера stdin) mFlagIsDebug=False #mPywinautoApplication=pywinauto.Application(backend="win32") mPywinautoApplication=pywinauto.Application(backend="uia") ############################################ ####Межпроцессное взаимодействие ############################################ #ProcessParentReadWaitString def ProcessParentReadWaitString(): #Выполнить чтение строки #ctypes.windll.user32.MessageBoxW(0, "Hello", "Your title", 1) lResult = sys.stdin.buffer.readline() #Вернуть потенциальные \n lResult = lResult.replace(b'{{n}}',b'\n') lResult = zlib.decompress(lResult[0:-1]) lResult = lResult.decode("utf-8") #Вернуть результат return lResult #ParentProcessWriteString def ProcessParentWriteString(lString): lByteString = zlib.compress(lString.encode("utf-8")) #Выполнить отправку строки в родительский процесс #Вернуть потенциальные \n lByteString = lByteString.replace(b'\n',b'{{n}}') sys.stdout.buffer.write(lByteString+bytes("\n","utf-8")) sys.stdout.flush(); return #ProcessParentWriteObject def ProcessParentWriteObject(inObject): #Выполнить отправку сконвертированного объекта в JSON ProcessParentWriteString(json.dumps(inObject)) return #ProcessParentReadWaitObject def ProcessParentReadWaitObject(): #Выполнить получение и разбор объекта lResult=json.loads(ProcessParentReadWaitString()); return lResult; ################################## ###Методы взаимодействия с GUI интерфейсом ################################## #pywinauto def GetControl(inControlSpecificationArray): #Подготовка взодного массива inControlSpecificationArray=ElementSpecificationArraySearchPrepare(inControlSpecificationArray) #Выполнить идентификацию объектов, если передан массив lResultList=[]; if len(inControlSpecificationArray) > 0: #Выполнить подключение к объекту lRPAApplication = mPywinautoApplication #Проверка разрядности lRPAApplication.connect(**inControlSpecificationArray[0]) lTempObject=lRPAApplication.window(**inControlSpecificationArray[0]) #Циклическое прохождение к недрам объекта for lWindowSpecification in inControlSpecificationArray[1:]: lTempObject=lTempObject.window(**lWindowSpecification) return lTempObject #Выполнить действие над элементом def ElementRunAction(inControlSpecificationArray,inActionName,inArgumentList=[],inkwArgumentObject={}): #Определить объект lObject=GetControl(inControlSpecificationArray) #Получить метод для вызова lFunction = getattr(lObject.wrapper_object(), inActionName) #Выполнить действие lFunction(*inArgumentList,**inkwArgumentObject) return def ElementGetInfo(inControlSpecificationArray): #Подготовка входного массива inControlSpecificationArray=ElementSpecificationArraySearchPrepare(inControlSpecificationArray) #Выполнить идентификацию объектов, если передан массив lResultList=[]; if len(inControlSpecificationArray) > 0: #Выполнить подключение к объекту lRPAApplication = mPywinautoApplication #Проверка разрядности lRPAApplication.connect(**inControlSpecificationArray[0]) lTempObject=lRPAApplication.window(**inControlSpecificationArray[0]) #Циклическое прохождение к недрам объекта for lWindowSpecification in inControlSpecificationArray[1:]: lTempObject=lTempObject.window(**lWindowSpecification) #Получить инфо объект lTempObjectInfo = lTempObject.wrapper_object().element_info #Добавить информацию об обнаруженом объекте lResultList.append(ElementInfoExportObject(lTempObjectInfo)); return lResultList #debug def ElementGetChildElementList(inControlSpecificationArray=[]): #Подготовка входного массива inControlSpecificationArray=ElementSpecificationArraySearchPrepare(inControlSpecificationArray) #Выполнить идентификацию объектов, если передан массив lResultList=[]; #ctypes.windll.user32.MessageBoxW(0, str(inControlSpecificationArray), "Your title", 1) if len(inControlSpecificationArray) > 0: #Выполнить подключение к объекту lRPAApplication = mPywinautoApplication lRPAApplication.connect(**inControlSpecificationArray[0]) lTempObject=lRPAApplication.window(**inControlSpecificationArray[0]) #Циклическое прохождение к недрам объекта for lWindowSpecification in inControlSpecificationArray[1:]: lTempObject=lTempObject.window(**lWindowSpecification) #Получить список дочерних объектов lTempChildList = lTempObject.wrapper_object().children() #Подготовить результирующий объект for lChild in lTempChildList: lTempObjectInfo=lChild.element_info #Добавить информацию об обнаруженом объекте lResultList.append(ElementInfoExportObject(lTempObjectInfo)); else: lResultList=GetRootElementList() return lResultList #Подготовить массив для обращшения к поиску элемементов def ElementSpecificationArraySearchPrepare(inControlSpecificationArray): lResult=[] #Циклический обход for lSpecificationItem in inControlSpecificationArray: lSpecificationItemNew=lSpecificationItem.copy() #Перебор всех элементов for lItemKey,lItemValue in lSpecificationItem.items(): #Флаг удаления атрибута lFlagRemoveAttribute=False ############################# #Если является вложенным словарем - удалить if type(lItemValue) is dict: lFlagRemoveAttribute=True #Является типом None if lItemValue is None: lFlagRemoveAttribute=True #Проверка допустимого ключевого слова if ( lItemKey == "class_name" or lItemKey == "class_name_re" or lItemKey == "parent" or lItemKey == "process" or lItemKey == "title" or lItemKey == "title_re" or lItemKey == "top_level_only" or lItemKey == "visible_only" or lItemKey == "enabled_only" or lItemKey == "best_match" or lItemKey == "handle" or lItemKey == "ctrl_index" or lItemKey == "found_index" or lItemKey == "predicate_func" or lItemKey == "active_only" or lItemKey == "control_id" or lItemKey == "control_type" or lItemKey == "auto_id" or lItemKey == "framework_id" or lItemKey == "backend"): True == True else: lFlagRemoveAttribute=True ############################# #Конструкция по удалению ключа из словаря if lFlagRemoveAttribute: lSpecificationItemNew.pop(lItemKey) #Добавить строку в результирующий массив lResult.append(lSpecificationItemNew) #Вернуть результат return lResult #Получить объект из атрибутов, которые удалось прочитать def ElementInfoExportObject(inElementInfo): #Подготовить выходную структуру данных lResult = {"name":None,"rich_text":None,"process_id":None,"handle":None,"class_name":None,"control_type":None,"control_id":None,"rectangle":{"left":None,"top":None,"right":None,"bottom":None}, 'runtime_id':None} #Проверка name try: lResult['name']=inElementInfo.name except Exception as e: True == False #Проверка rich_text try: lResult['rich_text']=inElementInfo.rich_text except Exception as e: True == False #Проверка process_id try: lResult['process_id']=inElementInfo.process_id except Exception as e: True == False #Проверка handle try: lResult['handle']=inElementInfo.handle except Exception as e: True == False #Проверка class_name try: lResult['class_name']=inElementInfo.class_name except Exception as e: True == False #Проверка control_type try: lResult['control_type']=inElementInfo.control_type except Exception as e: True == False #Проверка control_id try: lResult['control_id']=inElementInfo.control_id except Exception as e: True == False #Проверка rectangle left try: lResult['rectangle']['left']=inElementInfo.rectangle.left except Exception as e: True == False #Проверка rectangle right try: lResult['rectangle']['right']=inElementInfo.rectangle.right except Exception as e: True == False #Проверка rectangle top try: lResult['rectangle']['top']=inElementInfo.rectangle.top except Exception as e: True == False #Проверка rectangle bottom try: lResult['rectangle']['bottom']=inElementInfo.rectangle.bottom except Exception as e: True == False #Проверка runtime_id try: lResult['runtime_id']=inElementInfo.runtime_id except Exception as e: True == False #Вернуть результат return lResult def GetRootElementList(): #Получить список объектов lResultList=pywinauto.findwindows.find_elements() lResultList2=[] for lI in lResultList: lTempObjectInfo=lI lResultList2.append(ElementInfoExportObject(lI)); return lResultList2 def ElementDrawOutlineNew(inSpecificationArray): draw_outline_new(GetControl(inSpecificationArray)) return def draw_outline_new(lWrapperObject,colour='green',thickness=2,fill=win32defines.BS_NULL,rect=None): """ Draw an outline around the window. * **colour** can be either an integer or one of 'red', 'green', 'blue' (default 'green') * **thickness** thickness of rectangle (default 2) * **fill** how to fill in the rectangle (default BS_NULL) * **rect** the coordinates of the rectangle to draw (defaults to the rectangle of the control) """ #pdb.set_trace() # don't draw if dialog is not visible #if not lWrapperObject.is_visible(): # return colours = { "green": 0x00ff00, "blue": 0xff0000, "red": 0x0000ff, } # if it's a known colour if colour in colours: colour = colours[colour] if rect is None: rect = lWrapperObject.rectangle() # create the pen(outline) pen_handle = win32functions.CreatePen( win32defines.PS_SOLID, thickness, colour) # create the brush (inside) brush = win32structures.LOGBRUSH() brush.lbStyle = fill brush.lbHatch = win32defines.HS_DIAGCROSS brush_handle = win32functions.CreateBrushIndirect(ctypes.byref(brush)) # get the Device Context dc = win32functions.CreateDC("DISPLAY", None, None, None ) # push our objects into it win32functions.SelectObject(dc, brush_handle) win32functions.SelectObject(dc, pen_handle) # draw the rectangle to the DC win32functions.Rectangle( dc, rect.left, rect.top, rect.right, rect.bottom) # Delete the brush and pen we created win32functions.DeleteObject(brush_handle) win32functions.DeleteObject(pen_handle) # delete the Display context that we created win32functions.DeleteDC(dc) #run() lText = "Bitness:" + str(struct.calcsize("P") * 8) #for line in sys.stdin: # lText=lText+line; #ctypes.windll.user32.MessageBoxW(0, lText, "Your title", 1) buffer = "" lJSONInputString="" #Выполнить чтение буфера, если не отладка библиотеки if not mFlagIsDebug: #{'functionName':'', 'argsArray':[]} while True: try: lJSONInput = ProcessParentReadWaitObject() lJSONInputString=str(lJSONInput) #{'outputObject':''} #Выполнить вызов функции lResult=locals()[lJSONInput['functionName']](*lJSONInput['argsArray']) lJSONInput['outputObject']=lResult ProcessParentWriteObject(lJSONInput) except Exception as e: #Вывод ошибки в родительский поток ProcessParentWriteObject({'Error':str(e), 'ArgObject':str(lJSONInputString)}) else: print('Debug mode is turned on!') #if __name__ == '__main__': # if len(sys.argv) > 1: # lFunctionArgs = sys.argv[2:] # print(locals()[sys.argv[1]](*lFunctionArgs))