如何使用JNA运行Chrome? [英] How to run chrome using JNA?
问题描述
我写了一些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.
下面可能有类似的代码吗?
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屋!