如何使用JNA运行Chrome? [英] How to run chrome using JNA?

查看:116
本文介绍了如何使用JNA运行Chrome?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一些Java代码.

I wrote some java code.

如何在Windows(32位)中使用JNA运行chrome.

how to run chrome using JNA in windows(32bit).

然后我想获取它的书本.

then I like to get the hwnd of it.

如您所知,FindWindow是一种简单的解决方案,但是如果chrome无法运行,那么它将无法正常工作.

As you know, FindWindow is simple solution but if chrome doesn't running, it doesn't work.

FindWindow示例

下面可能有类似的代码吗?

below like code is possible?

HWND hwnd = User32.CreateProcess(...);


下面的代码打开镶边. 但是调整大小,最大化是行不通的.


below code open chrome. but sizing, maxmizing doesn't work.

public interface Kernel32 extends StdCallLibrary {
    Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);

    boolean CreateProcessA(
             String lpApplicationName
            , String lpCommandLine
            , Structure lpProcessAttributes
            , Structure lpThreadAttributes
            , boolean bInheritHandles
            , int dwCreationFlags
            , Structure lpEnvironment
            , String lpCurrentDirectory
            , Structure lpStartupInfo
            , Structure lpProcessInformation);
}


import com.sun.jna.Pointer;
import com.sun.jna.Structure;

public class ProcessInformation extends Structure {
    public Pointer hProcess;
    public Pointer hThread;
    public int dwProcessId;
    public int dwThreadId;
}


import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.WString;

public class StartupInfoA extends Structure {
    public int cb;
    public WString lpReserved;
    public WString lpDesktop;
    public WString lpTitle;
    public int dwX;
    public int dwY;
    public int dwXSize;
    public int dwYSize;
    public int dwXCountChars;
    public int dwYCountChars;
    public int dwFillAttribute;
    public int dwFlags;
    public short wShowWindow;
    public short cbReserved2;
    public Pointer lpReserved2;
    public Pointer hStdInput;
    public Pointer hStdOutput;
    public Pointer hStdError;
}


public class Test {
    public static void main(String[] args) {

        int STARTF_USEPOSITION = 0x00000004;
        int STARTF_USESIZE = 0x00000002;
        int STARTF_USESHOWWINDOW = 0x00000001;

        ProcessInformation processInformation = new ProcessInformation();
        StartupInfoA startupInfo = new StartupInfoA();
        startupInfo.dwX = 100;
        startupInfo.dwY = 100;
        startupInfo.dwXSize = 100;
        startupInfo.dwYSize = 100;    
        startupInfo.wShowWindow = (short) SW_MAXIMIZE;
        startupInfo.dwFlags = STARTF_USEPOSITION | STARTF_USESIZE;

        Kernel32.INSTANCE.CreateProcessA(new String("C:\\Users.....\\Google\\Chrome\\Application\\chrome.exe")
                , null
                , null
                , null
                , true
                , 0
                , null
                , null
                , startupInfo
                , processInformation);
    }
}

推荐答案

如果Chrome没有运行,则您将无法获得其窗口的句柄,因为这样的窗口不存在.您可能想要使用ProcessBuilder之类的软件来运行Chrome,然后调用以下代码:

If Chrome is not running, you can't get a handle of its window, of course, because such a window does not exist. You might want to run Chrome, using something like ProcessBuilder, then call something like this:

user32.EnumWindows( new WndEnumProc()
{

    @SuppressWarnings ( "AssignmentToMethodParameter" )
    public boolean callback ( int hWnd, int lParam )
    {
        if ( user32.IsWindow( hWnd ) )
        {
            if ( user32.IsWindowVisible( hWnd ) )
            {
                RECT r = new RECT();
                user32.GetWindowRect( hWnd, r );
                // if (r.left > -32000) // is not minimized
                //{
                String windowTitle = getWindowParentName( hWnd );
                String windowClass = getWindowParentClassName( hWnd );
                hWnd = user32.GetAncestor( hWnd, 3 );
                if ( !windowTitle.toLowerCase().equals( "program manager" ) && !windowClass.toLowerCase().equals( "progman" ) && !windowTitle.equals( "" ) && !windowClass.toLowerCase().equals( "shell_traywnd" ) )
                {
                    listOfWindows.put( hWnd, getWindowParentRectangle( hWnd ) );
                }
                // }
            }
            return true;
        }
        else
        {
            return false;
        }
    }
}, 0 );

当然,这已经是可以运行的代码,它具有某些特定于我的应用程序的条件.但主要思想是 使用WndEnumProc()调用EnumWindows,它将把找到的所有窗口放入集合(在我的情况下为HashMap).然后,在EnumWindows返回之后,您将在listOfWindows变量中包含一组窗口,并且如果在调用EnumWindows的过程中运行了Chrome,则可以获取该Chrome的hwnd.

Of course, this is already working code that has some conditions specific to my app. But the main idea is to call EnumWindows with a WndEnumProc() that will put all windows it finds to a collection ( in my case an HashMap ). Then after the EnumWindows returns, you will have a collection of windows in your listOfWindows variable and you will be able to get the hwnd of Chrome if it was running during the time EnumWindows was called.

您应该像这样在user32实例中定义EnumWindows:

You should define EnumWindows in your user32 instance like this:

/**
 * Enumerates all top-level windows on the screen by passing the handle to each window, in turn, to an application-defined callback function.
 * @param wndenumproc A pointer to an application-defined callback function.
 * @param lParam An application-defined value to be passed to the callback function.
 * @return if the function succeeded.
 * <a href="http://msdn.microsoft.com/en-us/library/ms633497(v=VS.85).aspx"> <b>Microsoft Reference</b></a><br>
 */
public boolean EnumWindows ( WndEnumProc wndenumproc, int lParam );

您还应该在一个类中定义WndEnumProc结构(我的名字叫Structures),如下所示:

You should also define your WndEnumProc structure in a class (mine was named Structures) something like this:

  public static interface WndEnumProc extends StdCallLibrary.StdCallCallback
    {

        boolean callback ( int hWnd, int lParam );
    }

希望有帮助.请注意,在执行所有操作时,Chrome必须正在运行.正如我在一开始所指出的那样,使用ProcessBuilder来运行它应该相对简单,或者如果您不想花太多时间在浏览器中,那么您可以使用

Hope that helps. Please note that Chrome must be running while you are doing all that magic. Running it, as I noted in the beginning, should be relatively straightforward using a ProcessBuilder or if you don't want to bother much and Chrome is in your path, you can use

System.getRuntime().exec("chrome.exe")

启动Chrome.

这篇关于如何使用JNA运行Chrome?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆