使用PID切换到特定窗口(进程ID)

时间:2012-06-18 09:33:26

标签: java runtime cmd

我正在开发一个使用Runtime类的Java Selenium程序。 Internet Explorer窗口有多个打开的实例。
我需要“Bring Front”只有一个特定窗口让selenium套件无误地运行。

我使用tasklist命令检索了特定的iexplore实例。 现在我有了这个过程的PID。

Process p = Runtime.getRuntime().exec("tasklist /FI \"WindowTitle eq Google\"");
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));  
String line = null;  
int count=1;
while ((line = in.readLine()) != null) {
    System.out.println(count + " " + line);
    count++;
}

如何使用其PID通过运行时命令行将进程置于最前面(使其成为活动窗口)?

修改:
有没有办法使用应用程序的PID从命令提示符切换到应用程序窗口?

2 个答案:

答案 0 :(得分:1)

要从命令提示符切换到应用程序窗口,您可以使用Windows脚本宿主的AppActivate功能。它接受ProcessID或window的标题作为其参数。这是一个简单的脚本:

set WshShell = CreateObject("WScript.Shell")
WshShell.AppActivate Wscript.Arguments(0)

然后使用cscript AppActivate.vbs 1234

调用脚本

答案 1 :(得分:0)

我试图将上述建议应用于完整的解决方案

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static org.apache.commons.io.FileUtils.writeStringToFile;
import static org.apache.commons.lang3.math.NumberUtils.toInt;

public class WindowSwither {
    private static final Pattern TASKLIST_CSV_PATTERN = Pattern.compile("\".*?\",\"(\\d+)\".*");
    private int pidActive = 0;
    private final List<Integer> pidList = new ArrayList<>();

    public WindowSwither(String exeName) throws IOException {
        Process p = Runtime.getRuntime().exec("tasklist /FI \"ImageName eq " + exeName + ".exe\" /FO CSV");
        for (String line : showProcessOut(p)) {
            Matcher m = TASKLIST_CSV_PATTERN.matcher(line);
            if (m.find()) {
                pidList.add(toInt(m.group(1)));
            }
        }
    }

    public void next() throws IOException {
        if (pidList.size() == 0) {
            System.out.println("List empty! Ignored.");
            return;
        }

        if (pidActive == 0) {
            pidActive = pidList.get(0);
            System.out.println("[0] " + pidActive);
        } else {
            Iterator<Integer> it = pidList.iterator();
            while (it.hasNext()) {
                Integer pid = it.next();
                if (pid == pidActive) {
                    break;
                }
            }
            if (it.hasNext()) {
                pidActive = it.next();
                System.out.println("[+] " + pidActive);
            } else {
                pidActive = pidList.get(0);
                System.out.println("[0] " + pidActive);
            }
        }
        activate(pidActive);
    }

    private static void activate(int pid) throws IOException {
        String pathname = System.getProperty("java.io.tmpdir") + "WindowSwintcherAppActivate.vbs";
        File file = new File(pathname);
        if (!file.exists()) {
            String content = "set WshShell = CreateObject(\"WScript.Shell\")\n" +
                    "WshShell.AppActivate Wscript.Arguments(0)";
            writeStringToFile(file, content, StandardCharsets.UTF_8);
        }
        Runtime.getRuntime().exec("cscript " + pathname + " " + pid);
    }

    private List<String> showProcessOut(Process p) throws IOException {
        List<String> list = new ArrayList<>();
        BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream(), "cp866"));
        String line;
        while ((line = in.readLine()) != null) {
            list.add(line);
        }
        return list;
    }
}

主班

public class EnumerateWindows {
    public static void main(String[] args) throws IOException, InterruptedException {
        WindowSwither swither = new WindowSwither("notepad");
        swither.next();
        Thread.sleep(1000);

        swither.next();
        Thread.sleep(1000);

        swither.next();
        Thread.sleep(1000);

        swither.next();
        Thread.sleep(1000);
    }

}