为了账号安全,请及时绑定邮箱和手机立即绑定

使用 C# 实现 Java 自动化的 WindowsAccessBridge

使用 C# 实现 Java 自动化的 WindowsAccessBridge

C#
BIG阳 2021-07-01 14:01:52
我尝试使用WindowsAccessBridge.dll.我可以获得窗口句柄但调用该函数isJavaWindow(System.IntPtr hWnd)总是返回false请在下面找到我的代码:    static void Main()    {        System.Int32 vmID = 0;        System.Int64 _acParent = 0;        string WndName = "GLOBUS EDU";        string ClassName = "SunAwtFrame";        Windows_run();        System.IntPtr hWnd = System.IntPtr.Zero;        hWnd = (System.IntPtr)FindWindow(ClassName, WndName);        bool Found = isJavaWindow(hWnd);        if (!Found) { throw new System.Exception("ERROR: Unable to find window by classname " + ClassName + " and " + WndName + "!"); }        System.Console.WriteLine("Application is finished. Press ENTER to exit...");        System.Console.ReadKey();    }互操作:    [return: System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.Bool)]    [System.Runtime.InteropServices.DllImport("WindowsAccessBridge-64.dll", CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl)]    private extern static bool getAccessibleContextFromHWNDFct(System.IntPtr hwnd, out System.Int32 vmID, out System.Int32 _acParent);    private static bool getAccesibleContextFromHWND(System.IntPtr hWnd, out System.Int32 vmID, out System.Int64 acParent)    {        System.Int32 ac = -1;        bool retVal = false;        getAccessibleContextFromHWNDFct(hWnd, out vmID, out ac);        acParent = ac;        return retVal;    }    [System.Runtime.InteropServices.DllImport("WindowsAccessBridge-64.dll", CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl)]    private extern static bool getAccessibleContextInfo(int vmID, System.IntPtr ac, out AccessibleContextInfo textInfo);该功能FindWindow运行良好,我也得到了窗口句柄,Spy++ 也向我展示了。类名SunAwtFrame正如 Spy++ 所说。我的 Java 应用程序以 64 位运行,但我尝试了所有库(-32、-64),并且还在 VS 配置管理器中从 x86 切换到 x64 并返回。AccessBridge 本身运行良好 - Java-Monkey-64.exe 可以监视我正在运行的 Java 应用程序。有没有人有想法,为什么这不起作用?
查看完整描述

2 回答

?
慕莱坞森

TA贡献1810条经验 获得超4个赞

这几天我一直在与你的问题作斗争。


我创建了一个枚举窗口的程序,它是 Java 应用程序(当然是在控制台应用程序上编写的),并捕获与您相同的问题。然后,我在 WPF 应用程序上重写它,枚举所有窗口,然后认识到:除了普通窗口之外,我看到一个名为“java access bridge”的奇怪窗口,问题很明显:


Windows_run 函数需要有一个活动的 Windows 消息泵。 另一种方式,您必须将它放在 WPF 应用程序的构造函数或类似的东西上。


if (result != FALSE) {

        while (GetMessage(&msg, NULL, 0, 0)) {

            TranslateMessage(&msg);

            DispatchMessage(&msg);

        }

        shutdownAccessBridge();

    }

Java Monkey 应用程序中的代码。


创建隐藏窗口后,它会使用已注册的消息执行 PostMessage。访问桥的 JVM 端响应此消息,并将另一条消息回发到创建的窗口。因此,他们通过这种方式进行交流。而且,只有在消息泵可以处理消息后才能调用 JAB 函数。这就是为什么 java 猴子需要使用回调来处理它的业务的原因。


查看完整回答
反对 回复 2021-07-10
?
慕尼黑8549860

TA贡献1818条经验 获得超11个赞

为类名传递 null,如下面的代码所示:


IntPtr hWnd = FindWindow(null, "GLOBUS EDU"); //cast to IntPtr is redundant

bool Found = isJavaWindow(hWnd);

参考这里是Pinvoke文档,它对我有用!


查看完整回答
反对 回复 2021-07-10
  • 2 回答
  • 0 关注
  • 1163 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信