如果某个应用程序处于焦点状态,请检查 Java
Check in Java if a certain application is in focus
我想知道某个应用程序是否在 Linux 中。说是GoogleChrome。为此,我写了一个 bash 在线班轮,它正确地做到了。
xdotool search --name --class 'google-chrome' | grep $(xdotool getactivewindow)
当此命令在终端中为运行时,它将打印终端本身的ID。为避免这种情况,运行 以下命令和 select Chrome 在三秒的时间跨度内。
sleep 3; xdotool search --name --class 'google-chrome' | grep $(xdotool getactivewindow)
问题是当我运行上面提到的来自Java的单行时,它似乎总是什么都不打印。这是我的代码:
String cmd = "xdotool search --name --class 'google-chrome' | grep $(xdotool getactivewindow)";
Process p = Runtime.getRuntime().exec(cmd);
String result = getCommandResult(p.getInputStream());
private static String getCommandResult(InputStream stream) throws IOException {
StringBuilder sb = new StringBuilder();
try (InputStreamReader isr = new InputStreamReader(stream);
BufferedReader in = new BufferedReader(isr)) {
String line;
while ((line = in.readLine()) != null) {
sb.append(line);
}
}
return sb.toString().trim();
}
我愿意接受不同的解决方案来解决这个问题。
如果您正在使用管道重定向,那么您必须调用 shell,或者您自己将输出从一个程序重定向到另一个程序。
但是,恕我直言,您根本不需要 grep
,只需:
- 枚举 windows 某些 class。
- 获取活动 window id 并检查活动 window 列表是否包含它。
示例(省略了 q&d,resource/error 处理):
private static List<String> exec(String... args) throws IOException {
List<String> result = new ArrayList<>();
String line;
BufferedReader reader = new BufferedReader(
new InputStreamReader(
new ProcessBuilder()
.command(args)
.start()
.getInputStream()));
while ((line = reader.readLine()) != null) {
result.add(line);
}
return result;
}
public static void main(String[] args) {
try {
Thread.sleep(3000);
String windowId = exec("xdotool", "getactivewindow").get(0);
System.out.println(windowId);
List<String> windowList = exec("xdotool", "search", "--name", "--class", "google-chrome");
System.out.println(windowList.contains(windowId));
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
正如barti_ddu所说,由于命令中的管道,这不起作用。您可以通过使用作为参数传递的命令创建一个 sh 进程来解决此问题:
String cmd = "xdotool search --name --class 'google-chrome' | grep $(xdotool getactivewindow)";
Process p = new ProcessBuilder("sh", "-c", cmd).start();
String result = getCommandResult(p.getInputStream());
为什么要将命令硬编码到 class 中?而是将您的命令放在 shell 脚本中并改为调用它。然后您可以灵活地更改命令而无需重新编译。
Process proc = Runtime.getRuntime().exec("./opt/scripts/myscript.sh");
... 根据您的应用程序,将 shell 脚本作为参数传递可能会更好。
private void runCommandLine(String script) {
try {
Process proc = Runtime.getRuntime().exec(script);
proc.waitFor();
int character;
while((character = proc.getInputStream().read()) != -1) {
System.out.write(character);
}
while((character = proc.getErrorStream().read()) != -1) {
System.err.write(character);
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
编辑:
如果您的目标是弄清楚 window 当前关注的是什么,那么与其尝试通过命令行执行某些操作,不如使用 JNA(Java Native Access)图书馆有可能做到这一点。
Find out what application (window) is in focus in Java
我想知道某个应用程序是否在 Linux 中。说是GoogleChrome。为此,我写了一个 bash 在线班轮,它正确地做到了。
xdotool search --name --class 'google-chrome' | grep $(xdotool getactivewindow)
当此命令在终端中为运行时,它将打印终端本身的ID。为避免这种情况,运行 以下命令和 select Chrome 在三秒的时间跨度内。
sleep 3; xdotool search --name --class 'google-chrome' | grep $(xdotool getactivewindow)
问题是当我运行上面提到的来自Java的单行时,它似乎总是什么都不打印。这是我的代码:
String cmd = "xdotool search --name --class 'google-chrome' | grep $(xdotool getactivewindow)";
Process p = Runtime.getRuntime().exec(cmd);
String result = getCommandResult(p.getInputStream());
private static String getCommandResult(InputStream stream) throws IOException {
StringBuilder sb = new StringBuilder();
try (InputStreamReader isr = new InputStreamReader(stream);
BufferedReader in = new BufferedReader(isr)) {
String line;
while ((line = in.readLine()) != null) {
sb.append(line);
}
}
return sb.toString().trim();
}
我愿意接受不同的解决方案来解决这个问题。
如果您正在使用管道重定向,那么您必须调用 shell,或者您自己将输出从一个程序重定向到另一个程序。
但是,恕我直言,您根本不需要 grep
,只需:
- 枚举 windows 某些 class。
- 获取活动 window id 并检查活动 window 列表是否包含它。
示例(省略了 q&d,resource/error 处理):
private static List<String> exec(String... args) throws IOException {
List<String> result = new ArrayList<>();
String line;
BufferedReader reader = new BufferedReader(
new InputStreamReader(
new ProcessBuilder()
.command(args)
.start()
.getInputStream()));
while ((line = reader.readLine()) != null) {
result.add(line);
}
return result;
}
public static void main(String[] args) {
try {
Thread.sleep(3000);
String windowId = exec("xdotool", "getactivewindow").get(0);
System.out.println(windowId);
List<String> windowList = exec("xdotool", "search", "--name", "--class", "google-chrome");
System.out.println(windowList.contains(windowId));
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
正如barti_ddu所说,由于命令中的管道,这不起作用。您可以通过使用作为参数传递的命令创建一个 sh 进程来解决此问题:
String cmd = "xdotool search --name --class 'google-chrome' | grep $(xdotool getactivewindow)";
Process p = new ProcessBuilder("sh", "-c", cmd).start();
String result = getCommandResult(p.getInputStream());
为什么要将命令硬编码到 class 中?而是将您的命令放在 shell 脚本中并改为调用它。然后您可以灵活地更改命令而无需重新编译。
Process proc = Runtime.getRuntime().exec("./opt/scripts/myscript.sh");
... 根据您的应用程序,将 shell 脚本作为参数传递可能会更好。
private void runCommandLine(String script) {
try {
Process proc = Runtime.getRuntime().exec(script);
proc.waitFor();
int character;
while((character = proc.getInputStream().read()) != -1) {
System.out.write(character);
}
while((character = proc.getErrorStream().read()) != -1) {
System.err.write(character);
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
编辑:
如果您的目标是弄清楚 window 当前关注的是什么,那么与其尝试通过命令行执行某些操作,不如使用 JNA(Java Native Access)图书馆有可能做到这一点。
Find out what application (window) is in focus in Java