31

I am trying to upgrade my application in Java to work only if a window of process with certain name is active. I have found out that this is possible by using JNI, but I have no idea how exactly to do that. I just could not find any description or example that would explain it. My question is - how to get process name of currently active window in Windows (via JNI, or anything else - I accept any another solution)?

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
Erveron
  • 1,908
  • 2
  • 25
  • 48
  • 1
    JNA ([Java Native Access](http://jna.java.net/)) is easier to use than JNI, but for either of them, JNI or JNA, you have to study how to use them via their tutorials and references and then you have to look through the window API for the proper function call. There are no short-cuts here. – Hovercraft Full Of Eels Jun 17 '11 at 22:04

3 Answers3

62

Save yourself some pain and use JNA. You will need to download jna.jar and jna-platform.jar for the Win32 API. The pinvoke wiki and MSDN are useful for finding the right system calls.

Anyway, here is the code to print the title and process of the currently active window.

import static enumeration.EnumerateWindows.Kernel32.*;
import static enumeration.EnumerateWindows.Psapi.*;
import static enumeration.EnumerateWindows.User32DLL.*;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.ptr.PointerByReference;

public class EnumerateWindows {
    private static final int MAX_TITLE_LENGTH = 1024;

    public static void main(String[] args) throws Exception {
        char[] buffer = new char[MAX_TITLE_LENGTH * 2];
        GetWindowTextW(GetForegroundWindow(), buffer, MAX_TITLE_LENGTH);
        System.out.println("Active window title: " + Native.toString(buffer));

        PointerByReference pointer = new PointerByReference();
        GetWindowThreadProcessId(GetForegroundWindow(), pointer);
        Pointer process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pointer.getValue());
        GetModuleBaseNameW(process, null, buffer, MAX_TITLE_LENGTH);
        System.out.println("Active window process: " + Native.toString(buffer));
    }

    static class Psapi {
        static { Native.register("psapi"); }
        public static native int GetModuleBaseNameW(Pointer hProcess, Pointer hmodule, char[] lpBaseName, int size);
    }

    static class Kernel32 {
        static { Native.register("kernel32"); }
        public static int PROCESS_QUERY_INFORMATION = 0x0400;
        public static int PROCESS_VM_READ = 0x0010;
        public static native int GetLastError();
        public static native Pointer OpenProcess(int dwDesiredAccess, boolean bInheritHandle, Pointer pointer);
    }

    static class User32DLL {
        static { Native.register("user32"); }
        public static native int GetWindowThreadProcessId(HWND hWnd, PointerByReference pref);
        public static native HWND GetForegroundWindow();
        public static native int GetWindowTextW(HWND hWnd, char[] lpString, int nMaxCount);
    }
}
user692942
  • 16,398
  • 7
  • 76
  • 175
Garrett Hall
  • 29,524
  • 10
  • 61
  • 76
  • arrived here from another question, nice sample, saves a lot of time. +1 – BigMike May 22 '12 at 07:18
  • just what i was looking for .. great examples save time ! – Makarand Jun 17 '13 at 14:42
  • 5
    "The import 'enumeration' cannot be resolved".. what am I missing ?! – Reacen Oct 19 '13 at 04:39
  • 4
    @Reacen It is referencing the static classes that are created inside the `EnumerateWindows `class which he/she created. It might be helpful for users to see the `package enumeration;` at the start of the code. It had me `??` for a second. – ug_ Mar 08 '15 at 01:53
12

This code works with JNA 4.0

import com.sun.jna.Native;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.RECT;

// see http://java-native-access.github.io/jna/4.0/javadoc/

public class EnumerateWindows {
    private static final int MAX_TITLE_LENGTH = 1024;

    public static void main(String[] args) throws Exception {
        char[] buffer = new char[MAX_TITLE_LENGTH * 2];
        HWND hwnd = User32.INSTANCE.GetForegroundWindow();
        User32.INSTANCE.GetWindowText(hwnd, buffer, MAX_TITLE_LENGTH);
        System.out.println("Active window title: " + Native.toString(buffer));
        RECT rect = new RECT();
        User32.INSTANCE.GetWindowRect(hwnd, rect);
        System.out.println("rect = " + rect);
    }
 }
rogerdpack
  • 62,887
  • 36
  • 269
  • 388
John Henckel
  • 10,274
  • 3
  • 79
  • 79
0

Simply

import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.win32.StdCallLibrary;

public class WinSysUser32HWND {
    public interface User32 extends StdCallLibrary {
        User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class);
        HWND GetForegroundWindow();
        void GetWindowTextW(HWND hWnd, char[] lpString, int nMaxCount);
    }

    public static void main(String[] args) {
        char[] buffer = new char[1024 * 2];
        User32.INSTANCE.GetWindowTextW(User32.INSTANCE.GetForegroundWindow(), buffer, 1024);
        System.out.println("Active window title: " + Native.toString(buffer));
    }
}
Dev_java
  • 11
  • 2