这是我的代码,应该打印当前使用的应用程序的名称:
import com.sun.jna.Native;
import com.sun.jna.platform.win32.*;
import com.sun.jna.ptr.IntByReference;
public class AppList {
public static void main(String[] args) {
// PRINT TITLE OF ACTIVE WINDOW (NOT WANTED)
User32 user32 = User32.INSTANCE;
WinDef.HWND hwnd = user32.GetForegroundWindow();
char[] title = new char[1024];
user32.GetWindowText(hwnd, title, title.length);
System.out.println("Active window: " + String.valueOf(title));
// "Active window: Project4 - AppList.java"
// PRINT PATH OF ACTIVE APP AND FORMAT IT (BETTER BUT STILL NOT WANTED)
IntByReference processId = new IntByReference();
int id = user32.GetWindowThreadProcessId(hwnd, processId);
WinNT.HANDLE processHandle = Kernel32.INSTANCE.OpenProcess(
WinNT.PROCESS_QUERY_INFORMATION | WinNT.PROCESS_VM_READ, false, processId.getValue());
char[] exePath = new char[1024];
Psapi.INSTANCE.GetModuleFileNameExW(processHandle, null, exePath, exePath.length);
String exePathStr = Native.toString(exePath);
System.out.println(exePathStr);
// "C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2023.3.2\bin\idea64.exe"
// FORMAT IT
String activeAppName = exePathStr.substring(exePathStr.lastIndexOf("\\") + 1)
.replace(".exe", "").toLowerCase();
char firstChar = Character.toUpperCase(activeAppName.charAt(0));
activeAppName = firstChar + activeAppName.substring(1);
System.out.println(activeAppName);
Kernel32.INSTANCE.CloseHandle(processHandle);
// "Idea64" instead of "InteliJ IDEA"
// "Chrome" instead of "Google Chrome"
// "Applicationframehost" instead of "Settings"
// Task manager doesn't work at all
}
}
如您所见,它无法正常工作。我想获取任务管理器中的应用程序名称(InteliJ IDEA、Google Chrome)
-使用第一个选项给我窗口标题。在某些情况下效果很好,但通常很糟糕。
-使用第二个选项为我提供当前应用程序的路径并对其进行格式化。在某些情况下也能很好地工作(例如 Spotify),但在大多数情况下,它会给我一些奇怪的名称,或者根本不起作用。
我花了几个小时在谷歌上搜索并询问人工智能,但我找不到任何东西。这些是我找到的唯一选择。
经过一番努力尝试找出如何使用 JNA 并使用 Win32 API 正确指定和操作参数后,我得到了一个工作示例,但最终与我给出的链接完全不同 - 这太手动了:
import com.sun.jna.platform.win32.*;
import com.sun.jna.Memory;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
public class AppList {
public static void main(String[] args) {
// Just my luck, Eclipse doesn't have version info in it. This one does...
String testAppFilespec = "D:\\Programming\\Android\\Android Studio\\bin\\studio64.exe";
String appDescription = "<Unable to retrieve>";
// Find out how big the VERSIONINFO structure in the file is.
IntByReference hVerHandle = new IntByReference();
int verSize = Version.INSTANCE.GetFileVersionInfoSize(testAppFilespec, hVerHandle);
// Create a memory buffer and try to grab the version info into it.
if (verSize > 0) {
Memory pInfoStruct = new Memory(verSize);
boolean gotInfo = Version.INSTANCE.GetFileVersionInfo(testAppFilespec,
0, verSize,
pInfoStruct);
if (gotInfo) {
// Grab the list of language / codepage pairs.
PointerByReference pLangCodePageList = new PointerByReference(null);
IntByReference pCPSize = new IntByReference();
if (Version.INSTANCE.VerQueryValue(pInfoStruct,
"\\VarFileInfo\\Translation",
pLangCodePageList, pCPSize)
&& pCPSize.getValue() > 0) {
// We'll use the description from the first entry only:
// pCPSize.getValue() has the number of bytes in ONE
// language / codepage entry.
// Don't use getPointer() here!!! Had me scratching my head
// for hours...
Pointer pEntry = pLangCodePageList.getValue();
byte[] langCodePageBytes
= pEntry.getByteArray(0, pCPSize.getValue() );
// Format the name of the sub-block containing the
// description of this app (watch byte order here):
String subBlockName
= "\\StringFileInfo\\"
+ String.format("%02x", langCodePageBytes[1] )
+ String.format("%02x", langCodePageBytes[0] )
+ String.format("%02x", langCodePageBytes[3] )
+ String.format("%02x", langCodePageBytes[2] )
+ "\\FileDescription";
// Now ask for this value out of the full info struct:
PointerByReference pDesc = new PointerByReference();
if (Version.INSTANCE.VerQueryValue(pInfoStruct,
subBlockName,
pDesc, pCPSize)
&& pCPSize.getValue() > 0) {
// Strings are all wide from this info struct:
appDescription = pDesc.getValue().getWideString(0);
}
}
}
}
System.out.println("App description: " + appDescription);
}
}
享受吧!
(注意:您可能必须在顶部包含一个包声明 - 我在 Eclipse 中这样做,但我已将其排除在这段代码之外。)