我设法从带有 jab 的 java 小程序中的某些控件中获取描述或名称,并且单击操作也成功运行。java小程序需要一些时间来响应点击动作,在点击动作之后,有时python脚本会继续运行剩余的行,但有时会崩溃并关闭而没有错误消息。在下面的代码中,我想将文本内容设置为文本框并单击按钮 5 次,不幸的是它总是在第一轮后崩溃。
在这里补充一点,我发现当我在运行下面的代码时手动单击该小程序上的某个按钮时,或者当单击操作发布并且小程序本身会执行一些响应时,此时下面的代码将始终停止运行。
还有一点我发现,在python脚本运行期间,applet中的任何状态变化都会导致python内核死机。比如点击动作是post,一些新的信息会出现在applet中,然后python内核就死掉了。
import ctypes
import ctypes.wintypes
import threading
user32 = ctypes.windll.user32
import time
#=================================================================
def initialize():
bridgeDll = cdll.LoadLibrary(r'C:\XXX\windowsaccessbridge-64.dll')
# Accept wm_copydata and any wm_user messages from other processes even if running with higher privileges
if not windll.user32.ChangeWindowMessageFilter(winUser.WM_COPYDATA, 1):
raise WinError()
for msg in range(winUser.WM_USER + 1, 0xffff):
if not windll.user32.ChangeWindowMessageFilter(msg, 1):
raise WinError()
bridgeDll.Windows_run()
#=================================================================
class MyThread(threading.Thread):
def run(self):
msg = ctypes.wintypes.MSG()
initialize()
while user32.GetMessageW(ctypes.byref(msg), None, 0, 0):
user32.TranslateMessage(msg)
user32.DispatchMessageW(msg)
print('End of GetMessageW')
#=================================================================
#call dll initialize in the thread
t = MyThread()
t.start()
time.sleep(1)
#=================================================================
hwnd = 0x000D0E7A
print('java window is ', isJavaWindow(hwnd)) # java window is 1
#=================================================================
#To create instance
class JABContext(object):
def __init__(self,hwnd=None,vmID=None,accContext=None):
if hwnd and not vmID:
vmID=c_long()
accContext=JOBJECT64()
bridgeDll.getAccessibleContextFromHWND(hwnd,byref(vmID),byref(accContext))
#Record this vm ID and window handle for later use with other objects
vmID=vmID.value
vmIDsToWindowHandles[vmID]=hwnd
elif vmID and not hwnd:
hwnd = getWindowHandleFromAccContext(vmID,accContext)
self.hwnd=hwnd
self.vmID=vmID
self.accContext=accContext
def getAccessibleContextInfo(self):
info=AccessibleContextInfo()
bridgeDll.getAccessibleContextInfo(self.vmID,self.accContext,byref(info))
return info
def getAccessibleTextItems(self,index):
textItemsInfo=AccessibleTextItemsInfo()
bridgeDll.getAccessibleTextItems(self.vmID,self.accContext,byref(textItemsInfo),index)
return textItemsInfo
def getAccessibleChildFromContext(self,index):
accContext=bridgeDll.getAccessibleChildFromContext(self.vmID,self.accContext,index)
if accContext:
return self.__class__(self.hwnd,self.vmID,accContext)
else:
return None
#To input words into text controls
def setTextContents(self, word):
bridgeDll.setTextContents(self.vmID,self.accContext,word)
#To get actions structure
def getAccessibleActions(self):
info = AccessibleActions()
bridgeDll.getAccessibleActions(self.vmID,self.accContext,byref(info))
return info
#To do actions click
def doAccessibleActions(self, AccessibleActionsToDo):
info = AccessibleActionsToDo
failure = jint()
bridgeDll.doAccessibleActions(self.vmID,self.accContext,byref(info),byref(failure))
return failure
Jab = JABContext(hwnd = hwnd,vmID = None, accContext = None)
Textbox = Jab.getAccessibleChildFromContext(index = 0)
button = Jab.getAccessibleChildFromContext(index = 1)
#=================================================================
list_test = [1,2,3,4,5]
for num in list_test:
#set text
Textbox.setTextContents(num)
TempNum = Textbox.getAccessibleTextItems(index = 0).word
if TempNum != num:
print('input error')
print('input finished')
#click on button
getAccessibleActions = button.getAccessibleActions()
aa = button.doAccessibleActions(getAccessibleActions)
if aa == 0:
print('click failure')
print('click' finished)