
java标准api无法直接通过processhandle获取窗口标题,但可借助操作系统命令(如windows的tasklist或linux/macos的xwininfo/wmctrl)结合runtime执行shell命令来实现。
在Java中,ProcessHandle(自Java 9引入)提供了对进程基本信息(如用户、启动命令、命令行参数、启动时间等)的安全访问能力,但其ProcessHandle.Info接口不包含窗口标题(Window Title)字段。这是因为窗口标题属于GUI层面的属性,由操作系统窗口管理器维护,与底层进程本身无直接映射关系——同一进程可能拥有多个窗口、无窗口(如后台服务),或窗口标题动态变化,因此JVM未将其纳入跨平台进程抽象。
若需获取指定进程ID(PID)对应窗口的标题,必须依赖操作系统原生机制,并通过Java调用外部命令实现。以下是分平台的实用方案:
✅ Windows:使用 tasklist + 文本过滤
Windows系统可通过tasklist /v /fo list输出详细进程信息(含“Window Title”字段),再用find筛选:
public static void getWindowTitleByPidOnWindows(long pid) throws IOException, InterruptedException {
String command = String.format("tasklist /v /fo list /fi \"pid eq %d\" | findstr /i \"Window Title\"", pid);
Process process = Runtime.getRuntime().exec(command);
process.waitFor();
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
if (line.trim().startsWith("Window Title:")) {
String title = line.substring("Window Title:".length()).trim();
System.out.println("窗口标题: " + title);
return;
}
}
System.out.println("未找到PID=" + pid + "对应的窗口标题(可能无GUI窗口或权限不足)");
}
}⚠️ 注意:需以管理员权限运行Java程序才能获取其他用户进程的窗口信息;普通用户仅能看到自身进程。
✅ Linux(X11):使用 wmctrl 或 xwininfo
需先安装工具:sudo apt install wmctrl(Ubuntu/Debian)或 brew install wmctrl(macOS + XQuartz)。
wmctrl -lp 可列出所有窗口及其关联PID:
本文档主要讲述的是j2me3D游戏开发简单教程; 如今,3D图形几乎是任何一部游戏的关键部分,甚至一些应用程序也通过用3D形式来描述信息而获得了成功。如前文中所述,以立即模式和手工编码建立所有的3D对象的方式进行开发速度很慢且很复杂。应用程序中多边形的所有角点必须在数组中独立编码。在JSR 184中,这称为立即模式。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
public static void getWindowTitleByPidOnLinux(long pid) throws IOException {
Process process = Runtime.getRuntime().exec("wmctrl -lp");
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
// 输出格式示例: 0x04a00003 0 12345 user Desktop
String[] parts = line.trim().split("\\s+");
if (parts.length >= 3) {
try {
long windowPid = Long.parseLong(parts[2]);
if (windowPid == pid) {
// 取出窗口标题(从第4列开始合并)
String title = String.join(" ", Arrays.copyOfRange(parts, 3, parts.length));
System.out.println("窗口标题: " + title);
return;
}
} catch (NumberFormatException ignored) {}
}
}
System.out.println("未找到PID=" + pid + "关联的X11窗口");
}
}✅ macOS:使用 AppleScript(推荐)
macOS无直接PID→窗口标题命令,但可通过AppleScript查询前台/所有应用窗口:
public static void getWindowTitleByPidOnMacOS(long pid) throws IOException, InterruptedException {
// 获取进程名(用于后续匹配)
String psCmd = "ps -o comm= -p " + pid;
Process psProc = Runtime.getRuntime().exec(psCmd);
psProc.waitFor();
String appName = "";
try (BufferedReader br = new BufferedReader(
new InputStreamReader(psProc.getInputStream()))) {
appName = br.readLine().trim().replaceAll("\\.app$", "");
}
// 用AppleScript遍历所有应用窗口,匹配进程名
String script = String.format(
"osascript -e 'use sys: \"System Events\"' " +
"-e 'repeat with p in every application process whose unix id is %d' " +
"-e 'repeat with w in windows of p' " +
"-e 'if name of w is not missing value then log name of w' " +
"-e 'end repeat' " +
"-e 'end repeat'",
pid
);
Process appScript = Runtime.getRuntime().exec(script);
appScript.waitFor();
try (BufferedReader br = new BufferedReader(
new InputStreamReader(appScript.getInputStream()))) {
String line;
while ((line = br.readLine()) != null) {
if (line.contains("log: ")) {
System.out.println("窗口标题: " + line.substring("log: ".length()).trim());
return;
}
}
}
}? 安全与兼容性提醒
- 不要拼接不可信输入到命令字符串中,避免命令注入(应使用ProcessBuilder+参数列表替代字符串拼接);
- 跨平台代码需做OS检测(System.getProperty("os.name"));
- GUI进程可能因权限、沙盒(如macOS App Sandbox)、Wayland(Linux新显示协议)限制而无法被枚举;
- Runtime.exec() 启动的进程默认不继承父进程环境变量,必要时需显式设置;
- 建议添加超时控制(如process.waitFor(5, TimeUnit.SECONDS))防止挂起。
综上,获取窗口标题本质是平台特定任务,Java需作为“胶水语言”桥接OS能力。核心思路始终是:用PID定位进程 → 调用OS工具枚举其GUI窗口 → 解析输出提取标题。









