如何使用 JNA 运行 chrome?

2024-03-16

我写了一些java代码。

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

然后我喜欢了解它的含义。

如您所知,FindWindow 是一个简单的解决方案,但如果 chrome 不运行,它就不起作用。

查找窗口示例 http://javadevelopersdiary.blogspot.com/2008/03/call-findwindow-method-of-user32dll.html

下面的代码可以吗?

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

下面的代码打开chrome。 但调整大小、最大化是行不通的。


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 没有运行,您就无法获取其窗口的句柄,因为这样的窗口不存在。你可能想要运行 Chrome,使用 ProcessBuilder 之类的东西,然后调用如下所示的东西:

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 变量中将包含一个窗口集合,并且如果 Chrome 在调用 EnumWindows 期间正在运行,您将能够获取 Chrome 的 hwnd。

您应该在 user32 实例中定义 EnumWindows,如下所示:

/**
 * 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),如下所示:

  public static interface WndEnumProc extends StdCallLibrary.StdCallCallback
    {

        boolean callback ( int hWnd, int lParam );
    }

希望有帮助。请注意,当您执行所有这些操作时,Chrome 必须正在运行。正如我在开始时提到的,使用 ProcessBuilder 运行它应该相对简单,或者如果您不想太麻烦并且 Chrome 在您的路径中,您可以使用

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

启动 Chrome。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 JNA 运行 chrome? 的相关文章

随机推荐