(将 c# 转换为 Java JNA) - 从 hwnd GetModuleFileName

发布于 2024-12-06 05:03:53 字数 1869 浏览 0 评论 0原文

我正在尝试准确地执行这里所做的操作: 如果我只有一个窗口句柄 (hWnd),我该如何 GetModuleFileName()?

但是是在 java 而不是 C# 中。

到目前为止,我已经做到了这一点:

public static final int PROCESS_QUERY_INFORMATION = 0x0400;

public interface User32 extends StdCallLibrary {
    User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class);
    int GetWindowThreadProcessId(HWND hwnd, IntByReference pid);
};

public interface Kernel32 extends StdCallLibrary {
    Kernel32 INSTANCE = (Kernel32)Native.loadLibrary("kernel32", Kernel32.class);
    public Pointer OpenProcess(int dwDesiredAccess, boolean bInheritHandle, int dwProcessId);
    public int GetTickCount();
};

public interface psapi extends StdCallLibrary {
    psapi INSTANCE = (psapi)Native.loadLibrary("psapi", psapi.class);
    int GetModuleFileNameExA (Pointer process, Pointer hModule, byte[] lpString, int nMaxCount);

};


public static String getModuleFilename(HWND hwnd)
{

    byte[] exePathname = new byte[512];

    Pointer zero = new Pointer(0);
    IntByReference pid = new IntByReference();
    User32.INSTANCE.GetWindowThreadProcessId(hwnd, pid);
    System.out.println("PID is " + pid.getValue());

    Pointer process = Kernel32.INSTANCE.OpenProcess(PROCESS_QUERY_INFORMATION, false, pid.getValue());
    int result = psapi.INSTANCE.GetModuleFileNameExA(process, zero, exePathname, 512);
    String text = Native.toString(exePathname).substring(0, result);
    return text;



}

给定的窗口句柄是有效的,并且 PID 始终打印成功。 “Process”似乎返回一个值,但“result”始终为零。任何了解 JNA 的人都可以告诉我我的错误在哪里吗?

编辑:最后,成功!问题出在这一行(其中第一个值必须是1040):

Pointer process = Kernel32.INSTANCE.OpenProcess(1040, false, pid.getValue());

I am trying to do exactly what is being done over here: How do I GetModuleFileName() if I only have a window handle (hWnd)?

But in java instead of C#.

So far I have managed to this:

public static final int PROCESS_QUERY_INFORMATION = 0x0400;

public interface User32 extends StdCallLibrary {
    User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class);
    int GetWindowThreadProcessId(HWND hwnd, IntByReference pid);
};

public interface Kernel32 extends StdCallLibrary {
    Kernel32 INSTANCE = (Kernel32)Native.loadLibrary("kernel32", Kernel32.class);
    public Pointer OpenProcess(int dwDesiredAccess, boolean bInheritHandle, int dwProcessId);
    public int GetTickCount();
};

public interface psapi extends StdCallLibrary {
    psapi INSTANCE = (psapi)Native.loadLibrary("psapi", psapi.class);
    int GetModuleFileNameExA (Pointer process, Pointer hModule, byte[] lpString, int nMaxCount);

};


public static String getModuleFilename(HWND hwnd)
{

    byte[] exePathname = new byte[512];

    Pointer zero = new Pointer(0);
    IntByReference pid = new IntByReference();
    User32.INSTANCE.GetWindowThreadProcessId(hwnd, pid);
    System.out.println("PID is " + pid.getValue());

    Pointer process = Kernel32.INSTANCE.OpenProcess(PROCESS_QUERY_INFORMATION, false, pid.getValue());
    int result = psapi.INSTANCE.GetModuleFileNameExA(process, zero, exePathname, 512);
    String text = Native.toString(exePathname).substring(0, result);
    return text;



}

The window handle that is given is valid, and the PID is always printed successfully. "Process" appears to return a value but the "result" is always zero. Could anyone knowledgeable about JNA kindly show me where my mistake is?

EDIT: Finally, SUCCESS! The problem was this line (where the first value had to be 1040):

Pointer process = Kernel32.INSTANCE.OpenProcess(1040, false, pid.getValue());

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

渔村楼浪 2024-12-13 05:03:53

这可能不是它失败的原因,但我认为 dwProcessId 参数应该是 int,而不是 IntByReference。

请参阅 MSDN (http://msdn.microsoft.com/en-us/library/ms684320(v=VS.85).aspx):

HANDLE WINAPI OpenProcess(
  __in  DWORD dwDesiredAccess,
  __in  BOOL bInheritHandle,
  __in  DWORD dwProcessId
);

它只是一个常规的 DWORD。

另外,您可以使用 GetLastError( ) 返回有关函数调用失败原因的更多信息。最后,这是一个不太可能的情况,但是您的 PROCESS_QUERY_INFORMATION 声明未包含在代码片段中 - 请确保它具有正确的值 (0x0400)。

This may not be the reason it's failing, but I think the dwProcessId parameter should be an int, not IntByReference.

See MSDN (http://msdn.microsoft.com/en-us/library/ms684320(v=VS.85).aspx):

HANDLE WINAPI OpenProcess(
  __in  DWORD dwDesiredAccess,
  __in  BOOL bInheritHandle,
  __in  DWORD dwProcessId
);

It's just a regular DWORD.

Also, you can use GetLastError() to return more information about why the function call failed. Finally, this is a long shot, but your declaration of PROCESS_QUERY_INFORMATION is not included in the code snippet -- make sure it has the correct value (0x0400).

木落 2024-12-13 05:03:53

为什么进程 ID 这么麻烦?

引用 GetModuleFilename()

hModule [输入,可选]:

正在请求其路径的已加载模块的句柄。如果
该参数为 NULL,GetModuleFileName 检索模块的路径
当前进程的可执行文件。

如果您想要当前进程的模块文件名,只需传递NULL作为进程ID。

如果您想要另一个进程的模块文件名,则在调用OpenProcess()之前需要特定的访问权限。 此处介绍了如何更改访问权限,实现起来相当困难(需要大量的步骤来查找权限名称、获取权限的luid、调整token的权限等)

why all the hassle with the process id ??

quoting from the documention of GetModuleFilename():

hModule [in, optional]:

A handle to the loaded module whose path is being requested. If
this parameter is NULL, GetModuleFileName retrieves the path of the
executable file of the current process.

if you want the module fileName of the current process, just pass NULL as the process id.

if you want the module filename of another process, you need specific access rights before calling OpenProcess(). changing the access rights is described here, and is quite difficult to achieve (it requires a great amount of steps to lookup the privilege name, get the luid of the privilege, adjust the privileges of the token, etc.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文