简体   繁体   English

C# 使用 Java Access Bridge 自动化 Java 应用程序

[英]C# to automate Java application with Java Access Bridge

I have a Java application that I want to automate for testing.我有一个 Java 应用程序,我想对其进行自动化测试。 Unfortunately, the app window only registers as a SunAWTFrame, which means none of the controls are exposed to typical window analysis and automation tools.不幸的是,应用程序 window 仅注册为 SunAWTFrame,这意味着没有任何控件暴露给典型的 window 分析和自动化工具。

My search has lead me to C# and utilising Java Access Bridge DLLS in a C# program to automate it.我的搜索引导我找到 C# 并在 C# 程序中使用 Java Access Bridge DLLS 来自动化它。

Has anyone had any experience of this?有没有人有这方面的经验?

Oracle provides JavaAccessBridge (JAB) with some DLLS to help with this as I understand it after reading a few articles around the inte.net. Oracle 提供了带有一些 DLLS 的 JavaAccessBridge (JAB) 来帮助解决这个问题,因为我在阅读了一些关于 inte.net 的文章后理解了它。 There are some code examples but I'm really not groking it right now.有一些代码示例,但我现在真的不是在摸索它。 By breaking it down, I think this is what needs to be achieved:通过分解,我认为这是需要实现的:

  1. Import / load / parse the JAB dlls导入/加载/解析 JAB dll
  2. Map functions in the JAB dll to methods / calls within my program Map JAB 中的函数 dll 到我程序中的方法/调用
  3. Have the Java application to automate run (with JAB enabled) and get handle of it to my program让 Java 应用程序自动运行(启用 JAB)并将其处理到我的程序
  4. Utilise the JAB functions to control the Java application利用 JAB 功能控制 Java 应用程序

I don't know C# as well as I know Java, but that's not going to stop me.我不知道 C#,也不知道 Java,但这不会阻止我。

If anyone can provide help, guidance, pointers or anything to get me started, that'd be truly awesome.如果有人可以提供帮助、指导、指示或任何帮助我入门的东西,那真是太棒了。

Building on Stackia's great tip to use Google's AccessBridgeExplorer, Here are some tips to get you going:基于 Stackia 关于使用 Google 的 AccessBridgeExplorer 的重要提示,以下是一些帮助您前进的提示:

  • Download Access Bridge Explorer下载Access Bridge Explorer

  • Use the WindowsAccessBridgeInterop.dll in your own (WinForms not Console) project (Add> Project Reference> Select the DLL)在您自己的(WinForms 而不是控制台)项目中使用 WindowsAccessBridgeInterop.dll(添加 > 项目参考 > Select DLL)

  • Create a new access bridge object新建访问网桥 object

    AccessBridge Java = new AccessBridge(); AccessBridge Java = new AccessBridge();

  • Initialize the Access Bridge object初始化接入网桥 object

    Java.Initialize(); Java.初始化();

  • Call Application.DoEvents() - A hack to wait for Java.Initialize to complete (My simple understanding is Java Access Bridge Uses a hidden window or similar) Call Application.DoEvents() - 等待 Java.Initialize 完成的 hack(我的简单理解是 Java Access Bridge Uses a hidden window or similar)

    Application.DoEvents();应用程序.DoEvents(); //this waits for Java Bridge to initilize;) //这等待 Java 桥初始化;)

  • Get the handle of the Java Window (plenty of examples online of how to get a Window Handle in C#)获取 Java Window 的句柄(网上有很多关于如何在 C# 中获取 Window 句柄的示例)

  • Get Access to the Java Object that represents the window:获取代表 window 的 Java Object:

    Java.Functions.GetAccessibleContextFromHWND(Handle, out int vmid, out JavaObjectHandle javaObjectHandle); Java.Functions.GetAccessibleContextFromHWND(句柄,出 int vmid,出 JavaObjectHandle javaObjectHandle);

  • Get AccessibleWindow Object for Window (so you can find its children)为 Window 获取 AccessibleWindow Object(这样你就可以找到它的孩子)

    AccessibleWindow win = Java.CreateAccessibleWindow(handle); AccessibleWindow win = Java.CreateAccessibleWindow(handle);

  • Come up with your own way to cycle through the children, and the childrens children until you find the object you are after:想出你自己的方式来循环遍历孩子,以及孩子的孩子,直到找到你想要的 object:

    //Similar to: foreach(var child in win.GetChildren()) JavaObjectHandle? //类似于:foreach(var child in win.GetChildren()) JavaObjectHandle? javaObject = Java.Functions.GetAccessibleChildFromContext(node.JvmId, parentJavaObject, child.GetIndexInParent()); javaObject = Java.Functions.GetAccessibleChildFromContext(node.JvmId, parentJavaObject, child.GetIndexInParent());

    //to get the label or title of the object: //获取 label 或 object 的标题:

    child.GetTitle();孩子.GetTitle();

  • To Interact with an object (eg click a button), do similar to the following: (please note where it says JavaObject - it means the child java object (eg. to click a button you need to get the JavaObject for that button using GetAccessibleChildFromContext as i mentioned above)要与 object 交互(例如单击按钮),请执行类似以下操作:(请注意它说 JavaObject 的位置 - 它表示子 java object(例如,要单击按钮,您需要使用 GetAccessibleChildFromContext 获取该按钮的 JavaObject正如我上面提到的)

    //Get Possible Actions JavaAutomation.Java.Functions.GetAccessibleActions(VMID, JavaObject, out AccessibleActions accessibleActions); //获取可能的操作 JavaAutomation.Java.Functions.GetAccessibleActions(VMID, JavaObject, out AccessibleActions accessibleActions);

     foreach( var action in accessibleActions.actionInfo) { Log.Info($"DoAction: {action.name}"); } AccessibleActionsToDo accessibleActionsToDo = new AccessibleActionsToDo(); accessibleActionsToDo.actions = accessibleActions.actionInfo; accessibleActionsToDo.actionsCount = accessibleActions.actionsCount; //Do Actions JavaAutomation.Java.Functions.DoAccessibleActions(VMID, JavaObject, ref accessibleActionsToDo, out int failure);

As of 2019 we have a great tool AccessBridgeExplorer created and open-sourced by google. 截至2019年,我们有一个很棒的工具AccessBridgeExplorer由Google创建并开源。 It's a really good staring point that contains a WindowsAccessBridgeInterop project which encapsulates almost every JAB API into a class oriented, .NET friendly assembly. 这是一个非常好的凝视点,其中包含一个WindowsAccessBridgeInterop项目,该项目将几乎每个JAB API封装到面向类,.NET友好的程序集中。

One notable thing, AccessBridge.Initialize() must be called in WPF/WinForm UI thread or in your own messaging pump thread, otherwise some methods like AccessBridge.EnumJvms() will always return false/empty. 一个值得注意的事情, AccessBridge.Initialize()必须在WPF / WinForm的UI线程或在您自己的消息泵线程调用,否则有些类似方法AccessBridge.EnumJvms()将始终返回false /空。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM