/* * Copyright (c) 2010-2016, Sikuli.org, sikulix.com * Released under the MIT License. * */ package org.sikuli.natives; import org.sikuli.basics.Debug; import org.sikuli.script.App; import org.sikuli.script.Key; import org.sikuli.script.RunTime; import org.sikuli.script.Screen; import java.awt.*; import java.io.File; import java.util.HashMap; import java.util.Map; public class WinUtil implements OSUtil { @Override public void checkFeatureAvailability() { RunTime.loadLibrary("WinUtil"); } @Override public App.AppEntry getApp(int appPID, String appName) { if (appPID == 0) { return null; } App.AppEntry app = null; Object filter; if (appPID < 0) { filter = appName; } else { filter = appPID; } String name = ""; String execName = ""; String options = ""; Integer pid = -1; String[] parts; if (filter instanceof String) { name = (String) filter; if (name.startsWith("!")) { name = name.substring(1); execName = name; } else { if (name.startsWith("\"")) { parts = name.substring(1).split("\""); if (parts.length > 1) { options = name.substring(parts[0].length() + 3); name = "\"" + parts[0] + "\""; } } else { parts = name.split(" "); if (parts.length > 1) { options = name.substring(parts[0].length() + 1); name = parts[0]; } } if (name.startsWith("\"")) { execName = new File(name.substring(1, name.length()-1)).getName().toUpperCase(); } else { execName = new File(name).getName().toUpperCase(); } } } else if (filter instanceof Integer) { pid = (Integer) filter; } else { return app; } Debug.log(3, "WinUtil.getApp: %s", filter); String cmd; if (pid < 0) { cmd = cmd = "!tasklist /V /FO CSV /NH /FI \"SESSIONNAME eq Console\""; } else { cmd = cmd = "!tasklist /V /FO CSV /NH /FI \"PID eq " + pid.toString() + "\""; } String result = RunTime.get().runcmd(cmd); String[] lines = result.split("\r\n"); if ("0".equals(lines[0].trim())) { for (int nl = 1; nl < lines.length; nl++) { parts = lines[nl].split("\""); if (parts.length < 2) { continue; } String theWindow = parts[parts.length - 1]; String theName = parts[1]; String thePID = parts[3]; //Debug.log(3, "WinUtil.getApp: %s:%s(%s)", thePID, theName, theWindow); if (!name.isEmpty()) { if ((theName.toUpperCase().contains(execName) && !theWindow.contains("N/A")) || theWindow.contains(name)) { return new App.AppEntry(theName, thePID, theWindow, "", ""); } } else { try { if (Integer.parseInt(thePID) == pid) { return new App.AppEntry(theName, thePID, theWindow, "", ""); } } catch (Exception ex) { } } } } else { Debug.logp(result); } if (!options.isEmpty()) { return new App.AppEntry(name, "", "", "", options); } if (app == null) { cmd = String.format("!tasklist /V /FO CSV /NH /FI \"IMAGENAME eq %s\"", execName); result = RunTime.get().runcmd(cmd); lines = result.split("\r\n"); if ("0".equals(lines[0].trim())) { for (int nl = 1; nl < lines.length; nl++) { parts = lines[nl].split("\""); if (parts.length < 2) { continue; } String theWindow = parts[parts.length - 1]; String theName = parts[1]; String thePID = parts[3]; if (theWindow.contains("N/A")) continue; app = new App.AppEntry(theName, thePID, theWindow, "", ""); break; } } } return app; } @Override public Map<Integer, String[]> getApps(String name) { Map<Integer, String[]> apps = new HashMap<Integer, String[]>(); String cmd; if (name == null || name.isEmpty()) { cmd = cmd = "!tasklist /V /FO CSV /NH /FI \"SESSIONNAME eq Console\""; } else { cmd = String.format("!tasklist /V /FO CSV /NH /FI \"IMAGENAME eq %s\"", name); } String result = RunTime.get().runcmd(cmd); String[] lines = result.split("\r\n"); if ("0".equals(lines[0].trim())) { for (int nl = 1; nl < lines.length; nl++) { String[] parts = lines[nl].split("\""); if (parts.length < 3) { continue; } String theWindow = parts[parts.length - 1]; String thePID = parts[3]; String theName = parts[1]; Integer pid = -1; try { pid = Integer.parseInt(thePID); } catch (Exception ex) { } if (pid != -1) { if (theWindow.contains("N/A")) { pid = -pid; } apps.put(pid, new String[] {theName, theWindow}); } } } else { Debug.logp(result); } return apps; } @Override public int isRunning(App.AppEntry app) { if (app.pid > 0) { return 1; } if (app.name.isEmpty()) { return -1; } if (getWindow(app.name, 0) != null) { return 1; } App.AppEntry ae = getApp(app.pid, app.name); if (ae != null && ae.pid > 0) { return 1; } return 0; } @Override public int open(String appName) { int pid = openApp(appName); return pid < 1 ? -1 : pid; } @Override public int open(App.AppEntry app) { if (app.pid > -1) { return switchApp(app.pid, 0); } String cmd = app.execName; if (!app.options.isEmpty()) { cmd += " " + app.options; } int pid = openApp(cmd); return pid < 1 ? -1 : pid; } @Override public int switchto(String appName) { return switchApp(appName, 0); } @Override public int switchto(String appName, int winNum) { return switchApp(appName, winNum); } @Override public int switchto(int pid, int num) { return switchApp(pid, num); } @Override public int switchto(App.AppEntry app, int num) { if (app.pid > -1) { String wname = app.window; if (wname.startsWith("!")) { wname = wname.substring(1); } return switchto(wname, 0); } if (app.window.startsWith("!")) { String token = app.window.substring(1); if(!token.isEmpty()) { return switchto(token, 0); } else { App.AppEntry newApp = getApp(app.pid, app.name); if (newApp == null) { return switchto(app.execName, 0); } else { return switchto(newApp.window, 0); } } } return switchto(app.execName, num); } @Override public int close(String appName) { return closeApp(appName); } @Override public int close(int pid) { return closeApp(pid); } @Override public int close(App.AppEntry app) { if (app.pid > -1) { return closeApp(app.pid); } if (app.window.startsWith("!")) { String token = app.window.substring(1); if(!token.isEmpty()) { switchto(app.window.substring(1), 0); RunTime.pause(1); new Screen().type(Key.F4, Key.ALT); return 0; } else { app = getApp(app.pid, app.name); } } if (app != null) { if (app.pid > -1) { return closeApp(app.pid); } else { return closeApp(app.execName.replaceAll("\"", "")); } } else { return -1; } } public native int switchApp(String appName, int num); public native int switchApp(int pid, int num); public native int openApp(String appName); public native int closeApp(String appName); public native int closeApp(int pid); @Override public Rectangle getWindow(String appName) { return getWindow(appName, 0); } @Override public Rectangle getWindow(int pid) { return getWindow(pid, 0); } @Override public Rectangle getWindow(String appName, int winNum) { long hwnd = getHwnd(appName, winNum); return _getWindow(hwnd, winNum); } @Override public Rectangle getWindow(int pid, int winNum) { long hwnd = getHwnd(pid, winNum); return _getWindow(hwnd, winNum); } @Override public Rectangle getFocusedWindow() { Rectangle rect = getFocusedRegion(); return rect; } @Override public native void bringWindowToFront(Window win, boolean ignoreMouse); private static native long getHwnd(String appName, int winNum); private static native long getHwnd(int pid, int winNum); private static native Rectangle getRegion(long hwnd, int winNum); private static native Rectangle getFocusedRegion(); private Rectangle _getWindow(long hwnd, int winNum) { Rectangle rect = getRegion(hwnd, winNum); return rect; } }