package com.sun.jna.examples.win32.ext; import com.sun.jna.Native; import com.sun.jna.examples.win32.Kernel32; import com.sun.jna.examples.win32.Psapi; import com.sun.jna.examples.win32.User32; import com.sun.jna.examples.win32.W32API.HANDLE; import com.sun.jna.examples.win32.W32API.HWND; import com.sun.jna.ptr.IntByReference; import static com.sun.jna.examples.win32.Kernel32.PROCESS_QUERY_INFORMATION; import static com.sun.jna.examples.win32.Kernel32.PROCESS_VM_READ; /** * A window visitor for processes that matches the name of the Windows process * module file and let the subclass deal with every matching process. * * @author <a href="mailto:phil.kursawe@gmail.com">Philipp Kursawe</a> * */ public abstract class ProcessWindowVisitor implements Visitor<HWND> { private final char filename[] = new char[260]; private final String[] processNames; private IntByReference processId = new IntByReference(); /** * @param processNames * in lower-case of the processes that the subclass in interested * in. */ protected ProcessWindowVisitor(String... processNames) { this.processNames = processNames; } public boolean visit(HWND window) { User32.INSTANCE.GetWindowThreadProcessId(window, processId); HANDLE process = Kernel32.INSTANCE.OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, false, processId.getValue()); if (process == null) { return true; } try { Psapi.INSTANCE.GetModuleFileNameEx(process, null, filename, filename.length); String path = Native.toString(filename).toLowerCase(); if (matchesProcessName(path)) { return visit(process, path, window); } } finally { Kernel32.INSTANCE.CloseHandle(process); } return true; } /** * Matches if one of the process names (given in the constructor) end with * the given <i>name</i>. * * <p> * Subclasses may override to provide their own matching function. * * @param name * of the process in lower case. * @return */ protected boolean matchesProcessName(String name) { for (String processName : processNames) { if (name.endsWith(processName)) return true; } return false; } protected abstract boolean visit(HANDLE process, String path, HWND window); }