2

I want to close an open web browser/browser tab for a specific URL from the java program. I am able to open the URL in internet explorer using the Desktop API from java.

Below is the code snippet to open the browser in IE

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

Now When I run the program again I want to make sure that there is no already instance where the above URL is opened in the browser. If it is so, close it and open it again in a new TAB or Browser window. This may look little weird requirement.

I know the basic approach should to get on to this issue is that, we need to identify the process and kill it and than again invoke the above code.

Any suggestion is welcome.

4

2 回答 2

3

我怀疑你可以用桌面做很多事情,因为你没有得到任何关于启动过程的参考。

我过去曾使用过这种技术(在 Java 6 之前,Desktop 不存在),因为它适用于 Process,你应该能够杀死它。

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 回答