WindowsAccessBridge для автоматизации Java с использованием C # - PullRequest
0 голосов
/ 29 мая 2018

Я пытаюсь автоматизировать Java-приложение, используя 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);

    [System.Runtime.InteropServices.DllImport("WindowsAccessBridge-64.dll", CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl, ThrowOnUnmappableChar = true, CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
    private extern static void Windows_run();

    [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
    private static extern System.IntPtr FindWindow(string lpClassName, string lpWindowName);

    [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
    private static extern System.IntPtr FindWindowByCaptionFct(System.IntPtr ZeroOnly, string lpWindowName);
    private static System.IntPtr FindWindowByCaption(string WindowTitle) { return FindWindowByCaptionFct(System.IntPtr.Zero, WindowTitle); }

    [System.Runtime.InteropServices.DllImport("WindowsAccessBridge-64.dll", CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl, ThrowOnUnmappableChar = true, CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
    private extern static System.Boolean isJavaWindow(System.IntPtr hwnd);

Функция FindWindow работает отлично, и я получаю дескриптор окна, также Spy ++ показывает мне.Имя класса SunAwtFrame, как говорит Spy ++.

Мои Java-приложения работают в 64-битном режиме, но я попробовал все библиотеки (-32, -64), а также переключился в VS Configuration Manager с x86 на x64 и обратно.

Сам AccessBridge работает хорошо - Java-Monkey-64.exe может подсмотреть мое работающее Java-приложение.

У кого-нибудь есть идеи, почему это не работает?

С уважением, Ян

1 Ответ

0 голосов
/ 20 мая 2019

Я боролся с вашей проблемой в течение нескольких дней.

Я создал программу, которая перечисляет окно, которое является java-приложением (конечно, пишет в консольном приложении), и обнаруживает ту же проблему, что и ваша.затем я переписываю его в приложении WPF, перечисляю все окна, затем освобождаю это: кроме обычного окна, я вижу странное окно с именем: «мост доступа к Java», и проблема явно:

функция Windows_run должна иметь активный насос сообщений Windows. другим способом, вы должны поместить его в конструктор приложения WPF или что-то такое же, что.

if (result != FALSE) {
        while (GetMessage(&msg, NULL, 0, 0)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        shutdownAccessBridge();
    }

код в Java Monkeyapplication.

После создания скрытого окна он выполняет PostMessage с зарегистрированным сообщением. Сторона JVM моста доступа отвечает на это сообщение и отправляет еще одно сообщение в созданное окно.Таким образом, они общаются таким образом.и более того, вы можете вызывать функции JAB только после того, как насос сообщений сможет обрабатывать сообщения.это причина, по которой Java-обезьяне нужно использовать обратный вызов для своего бизнеса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...