2

Java プログラムから特定の URL に対して開いている Web ブラウザー/ブラウザー タブを閉じたいです。Java のデスクトップ API を使用して Internet Explorer で URL を開くことができます。

以下は、IE でブラウザを開くためのコード スニペットです。

java.awt.Desktop desktop = java.awt.Desktop.getDesktop();
desktop.browse(new java.net.URI("http://www.xyzz.com"));

ここで、プログラムを再度実行するときに、上記の URL がブラウザーで開かれているインスタンスが既に存在しないことを確認したいと思います。その場合は、それを閉じて、新しいタブまたはブラウザ ウィンドウで再度開きます。これは少し奇妙な要件に見えるかもしれません。

この問題に取り組むための基本的なアプローチは、プロセスを特定して強制終了し、上記のコードを再度呼び出す必要があることです。

どんな提案でも大歓迎です。

4

2 に答える 2

3

起動されたプロセスへの参照が得られないため、デスクトップでできることはあまりないと思います。

私は過去にこの手法を使用しました (デスクトップが存在しない Java 6 より前)。プロセスで動作するため、強制終了できるはずです。

public static void openURL(String url) {
    StringBuilder sb = new StringBuilder();
    if (System.getProperty("os.name").indexOf("Windows")>-1) {
        String command = null;
        String urlLC = url.toLowerCase();
        if (urlLC.startsWith("https")) {
            command = WindowsCommandRetriever.getCommandForFileType("https");
        } else if (urlLC.startsWith("http")) {
            command = WindowsCommandRetriever.getCommandForFileType("http");
        }
        if (command == null) {
            command = WindowsCommandRetriever.commandForExtension(".html");
        }
        if (command.indexOf("%1") > -1) {
            sb.append(command.substring(0, command.indexOf("%1")));
            sb.append(url);
            sb.append(command.substring(command.indexOf("%1") + "%1".length()));
        } else {
            sb.append(command).append(' ');
            sb.append('"');
            sb.append(url);
            sb.append('"');
        }
    } else {
        sb.append("open ");
        sb.append(url);
    }
    try {
        final Process p = Runtime.getRuntime().exec(sb.toString());
        // Here you have the process. You can destroy it if you want
        // You need to figure out how you are going to handle this here.
    } catch (IOException e1) {
        e1.printStackTrace();
        System.err.println("Error while executing " + sb.toString());
    }
}

そして、WindowsCommandRetriever:

/*
 * (c) Copyright 2010-2011 AgileBirds
 *
 * This file is part of OpenFlexo.
 *
 * OpenFlexo is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * OpenFlexo is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>.
 *
 */

public class WindowsCommandRetriever {
    /**
     * 
     * @param extension
     *            the file extension (with or without the preceding '.')
     * @return the command to execute for the specified <code>extension</code> or null if there are no associated command
     */
    public static String commandForExtension(String extension) {
        String regKey = "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\" + extension;
        String fileType = WinRegistryAccess.getRegistryValue(regKey, "ProgID", WinRegistryAccess.REG_SZ_TOKEN);
        if (fileType == null) {
            StringBuilder sb = new StringBuilder("cmd /C assoc ");
            sb.append(extension.startsWith(".") ? extension : "." + extension);

            ConsoleReader reader;
            try {
                Process process = Runtime.getRuntime().exec(sb.toString());
                reader = new ConsoleReader(process.getInputStream());
                reader.start();
                process.waitFor();
                reader.join();
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            } catch (InterruptedException e) {
                e.printStackTrace();
                return null;
            }
            String result = reader.getResult();
            if (result.indexOf("=") > -1) {
                fileType = result.substring(result.indexOf("=") + 1).trim();
            }
        }
        if (fileType == null) {
            return null;
        }
        return getCommandForFileType(fileType);
    }

    public static String getCommandForFileType(String fileType) {
        String path = "HKEY_CLASSES_ROOT\\" + fileType + "\\shell\\open\\command";
        return WinRegistryAccess.getRegistryValue(path, null, WinRegistryAccess.REG_SZ_TOKEN);
    }
}


/*
 * (c) Copyright 2010-2011 AgileBirds
 *
 * This file is part of OpenFlexo.
 *
 * OpenFlexo is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * OpenFlexo is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>.
 *
 */

import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;


public class WinRegistryAccess {

    private static final String REGQUERY_UTIL = "reg query ";

    public static final String REG_SZ_TOKEN = "REG_SZ";

    public static final String REG_BINARY = "REG_BINARY";

    public static final String REG_DWORD_TOKEN = "REG_DWORD";

    /**
     * Returns the value for an attribute of the registry in Windows. If you want to now the processor speed of the machine, you will pass
     * the following path: "HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0" and the following attribute name: ~MHz
     * 
     * @param path
     *            - the registry path to the desired value
     * @param attributeName
     *            - the name of the attribute or null for the default
     * @param attributeType
     *            - the type of attribute (DWORD/SZ/...) default is REG_SZ
     * @return - the value for the attribute located in the given path
     */
    public static String getRegistryValue(String path, String attributeName, String attributeType) {
        if (attributeType == null) {
            attributeType = REG_SZ_TOKEN;
        }
        try {
            if (!path.startsWith("\"")) {
                path = "\"" + path + "\"";
            }
            StringBuilder sb = new StringBuilder();
            sb.append(REGQUERY_UTIL);
            sb.append(path);
            sb.append(' ');
            if (attributeName != null) {
                sb.append("/v ");
                sb.append(attributeName);
            } else {
                sb.append("/ve");
            }
            Process process = Runtime.getRuntime().exec(sb.toString());
            ConsoleReader reader = new ConsoleReader(process.getInputStream());
            reader.start();
            process.waitFor();
            reader.join();
            String result = reader.getResult();
            int p = result.indexOf(attributeType);
            if (p == -1) {
                return null;
            }
            return result.substring(p + attributeType.length()).trim();
        } catch (Exception e) {
            return null;
        }
    }

    public static class ConsoleReader extends Thread {
        private InputStream is;

        private StringWriter sw;

        ConsoleReader(InputStream is) {
            this.is = is;
            sw = new StringWriter();
        }

        @Override
        public void run() {
            try {
                int c;
                while ((c = is.read()) != -1) {
                    sw.write(c);
                }
            } catch (IOException e) {
                ;
            }
        }

        String getResult() {
            return sw.toString();
        }
    }

    public static String getJDKHome() {
        String key = "\"HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\"";
        String currentVersionAtt = "CurrentVersion";
        String javaHomeAtt = "JavaHome";
        String res1 = getRegistryValue(key, currentVersionAtt, null);
        String res2 = getRegistryValue(key + "\\" + res1, javaHomeAtt, null);
        return res2;
    }

    public static void main(String s[]) {
        String key = "\"HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\"";
        String currentVersionAtt = "CurrentVersion";
        String javaHomeAtt = "JavaHome";
        String res1 = getRegistryValue(key, currentVersionAtt, null);
        String res2 = getRegistryValue(key + "\\" + res1, javaHomeAtt, null);
        System.out.println("CurrentVersion '" + res1 + "'");
        System.out.println("JavaHome '" + res2 + "'");
    }
}
于 2012-04-09T16:19:49.113 に答える
2

これは、次の理由で不可能です。

a.) desktop.browse() によってどのプロセスが開始されるかわかりません。

b.) browse() によって開始されたプロセスが他に何の役に立つのかわかりません

忘れてください。なんとかハッキングできたとしても、確実に動作することはありません。

于 2012-04-09T16:10:22.460 に答える