public static HWND FindMainWindowFromPid(final long targetProcessId) { final List<HWND> resultList = new ArrayList<HWND>(); class ParentWindowCallback implements WinUser.WNDENUMPROC { @Override public boolean callback(HWND hWnd, Pointer lParam) { PointerByReference pointer = new PointerByReference(); User32Ex.instance.GetWindowThreadProcessId(hWnd, pointer); long pid = pointer.getPointer().getInt(0); if (pid == targetProcessId) if (resultList.isEmpty()) resultList.add(hWnd); return true; } } Api.User32Ex.instance.EnumWindows(new ParentWindowCallback(), 0); if (!resultList.isEmpty()) return resultList.get(0); return null; }
public static HWND findWind(final String name) { final User32 user32 = User32.INSTANCE; title=null; wind = null; user32.EnumWindows(new WNDENUMPROC() { public boolean callback(HWND hWnd, Pointer arg1) { char[] windowText = new char[512]; user32.GetWindowText(hWnd, windowText, 512); String wText = Native.toString(windowText); if (wText.contains(name)) { title = wText; wind = hWnd; return false; } return true; } }, null); return wind; }
/** * Gets a mapping from windows process id's to a list of windows associated with those process id's. All windows are returned, even windows that are usually hidden all the time. * @return * @uml.property name="windowProcess" */ private static Map<Integer, List<HWND>> getWindowProcessMap() { windowProcessMap = null; //Reset windowProcessMap every time. if (windowProcessMap == null) { User32 user32 = User32.INSTANCE; User32Ext myuser32 = User32Ext.INSTANCE; windowProcessMap = new HashMap<Integer, List<HWND>>(); final List<HWND> windows = new ArrayList<HWND>(); user32.EnumWindows(new WNDENUMPROC() { @Override public boolean callback(HWND hwnd, Pointer pntr) { windows.add(hwnd); return true; } }, Pointer.NULL); for (HWND window : windows) { IntByReference ibr = new IntByReference(); myuser32.GetWindowThreadProcessId(window, ibr); // System.out.printf("Putting window named %s in for process %d\n", // windowName, ibr.getValue()); List<HWND> winList = windowProcessMap.get(ibr.getValue()); if (winList == null) { winList = new ArrayList<HWND>(); windowProcessMap.put(ibr.getValue(), winList); } winList.add(window); } } return windowProcessMap; }
private void getWindows(User32 user32, final List<HWND> windows) { user32.EnumWindows(new WNDENUMPROC() { @Override public boolean callback(HWND hwnd, Pointer pntr) { windows.add(hwnd); return true; } }, Pointer.NULL); }
/** * An implementation of user32.FindWindow with Regex pattern matching * * @param windowClass the classname of the window, or null to ignore * @param titlePattern the regex pattern to match the title against * @return the hwnd of the found window, or null if not found */ public static WinDef.HWND findWindow(final String windowClass, final Pattern titlePattern) { ensureWinApiInstances(); final WinDef.HWND[] returnContainer = new WinDef.HWND[1]; user32.EnumWindows(new WNDENUMPROC() { /** * Callback is called synchronously... */ @Override public boolean callback(final HWND hWnd, final Pointer arg) { try { boolean checkWindowClass = (windowClass != null); final int length = user32.GetWindowTextLength(hWnd) + 1; if (length == 1) { return true; } final char[] windowText = new char[length]; user32.GetWindowText(hWnd, windowText, length); final String wText = Native.toString(windowText); String wClass = null; if (checkWindowClass || logger.isLoggable(Level.FINE)) { final char[] classText = new char[255]; User32.INSTANCE.GetClassName(hWnd, classText, 255); wClass = Native.toString(classText); } logger.fine("Detected window: " + wText + ", windowClass: " + wClass + ", HWND: " + hWnd); final boolean windowClassMatches = ! checkWindowClass || windowClass.equals(wClass); if (wText != null && windowClassMatches && titlePattern.matcher(wText).matches()) { logger.info("Matching window: " + wText + ", HWND: " + hWnd); returnContainer[0] = hWnd; return false; } } catch (final Throwable ex) { ex.printStackTrace(); } return true; } }, null); return returnContainer[0]; }
/** * Sends {@code WM_CLOSE} to the specified Windows {@link Process}. * * @param processInfo the {@link ProcessInfo} referencing the * {@link Process} to send to. * @return {@code true} if {@code WM_CLOSE} was sent, {@code false} * otherwise. */ protected boolean stopWindowsProcessWMClosed(@Nonnull ProcessInfo processInfo) { if (LOGGER.isTraceEnabled()) { LOGGER.trace( "Attempting to stop timed out process \"{}\" ({}) with WM_CLOSE", processInfo.getName(), processInfo.getPID() ); } HANDLE hProc = Kernel32.INSTANCE.OpenProcess( Kernel32.SYNCHRONIZE | Kernel32.PROCESS_TERMINATE, false, processInfo.getPID() ); if (hProc == null) { if (LOGGER.isTraceEnabled()) { LOGGER.trace( "Failed to get Windows handle for process \"{}\" ({}) during WM_CLOSE", processInfo.getName(), processInfo.getPID() ); } return false; } final Memory posted = new Memory(1); posted.setByte(0, (byte) 0); Memory dwPID = new Memory(4); dwPID.setInt(0, processInfo.getPID()); User32.INSTANCE.EnumWindows(new WNDENUMPROC() { @Override public boolean callback(HWND hWnd, Pointer data) { IntByReference dwID = new IntByReference(); User32.INSTANCE.GetWindowThreadProcessId(hWnd, dwID); if (dwID.getValue() == data.getInt(0)) { User32.INSTANCE.PostMessage(hWnd, User32.WM_CLOSE, new WPARAM(0), new LPARAM(0)); posted.setByte(0, (byte) 1); } return true; } }, dwPID); Kernel32.INSTANCE.CloseHandle(hProc); if (LOGGER.isTraceEnabled()) { if (posted.getByte(0) > 0) { LOGGER.trace( "WM_CLOSE sent to process \"{}\" ({}) with PostMessage", processInfo.getName(), processInfo.getPID() ); } else { LOGGER.trace( "Can't find any Windows belonging to process \"{}\" ({}), unable to send WM_CLOSE", processInfo.getName(), processInfo.getPID() ); } } return posted.getByte(0) > 0; }
private HWND getWindowHandle() { // Cache the window handle for five seconds to reduce CPU load and (possibly) minimise memory leaks long currentTime = System.currentTimeMillis(); if (currentTime < lastWindowsHandleCheck + 5000) { // It has been less than five seconds since the last check, so use the cached value return windowHandle; } else { debugLog.debug("Updating window handle ({}ms since last update)", currentTime - lastWindowsHandleCheck); lastWindowsHandleCheck = currentTime; windowHandle = null; } User32.INSTANCE.EnumWindows(new WNDENUMPROC() { @Override public boolean callback(HWND hWnd, Pointer arg1) { int titleLength = User32.INSTANCE.GetWindowTextLength(hWnd) + 1; char[] title = new char[titleLength]; User32.INSTANCE.GetWindowText(hWnd, title, titleLength); String wText = Native.toString(title); if (wText.isEmpty()) { return true; } PointerByReference pointer = new PointerByReference(); User32DLL.GetWindowThreadProcessId(hWnd, pointer); Pointer process = Kernel32.OpenProcess(Kernel32.PROCESS_QUERY_INFORMATION | Kernel32.PROCESS_VM_READ, false, pointer.getValue()); Psapi.GetModuleBaseNameW(process, null, baseNameBuffer, STRING_BUFFER_LENGTH); String baseNameString = Native.toString(baseNameBuffer); // see https://github.com/JeromeDane/HearthStats.net-Uploader/issues/66#issuecomment-33829132 User32.INSTANCE.GetClassName(hWnd, classNameBuffer, STRING_BUFFER_LENGTH); String classNameString = Native.toString(classNameBuffer); if (baseNameString.equals(processName) && classNameString.equals("UnityWndClass")) { windowHandle = hWnd; if (windowHandleId == null) { windowHandleId = windowHandle.toString(); if (lastKnownWindowHandleId == null || lastKnownWindowHandleId != windowHandleId) { // The window handle has changed, so try to find the location the HearthStats executable. This is used to // find the HS log file. Only compatible with Windows Vista and later, so we skip for Windows XP. lastKnownWindowHandleId = windowHandleId; if (Environment.isOsVersionAtLeast(6, 0)) { debugLog.debug("Windows version is Vista or later so the location of the Hearthstone is being determined from the process"); Kernel32.QueryFullProcessImageNameW(process, 0, processFileNameBuffer, lpdwSize); String processFileNameString = Native.toString(processFileNameBuffer); if (processFileNameString != null) { int lastSlash = processFileNameString.lastIndexOf('\\'); hearthstoneProcessFolder = processFileNameString.substring(0, lastSlash); } } } _notifyObserversOfChangeTo("Hearthstone window found with process name " + processName); } } return true; } }, null); // notify of window lost if (windowHandle == null && windowHandleId != null) { _notifyObserversOfChangeTo("Hearthstone window with process name " + processName + " closed"); windowHandleId = null; } return windowHandle; }
boolean EnumWindows (WNDENUMPROC wndenumproc, int lParam);
boolean EnumChildWindows(HWND hWnd, WNDENUMPROC lpEnumFunc, Pointer data);