在Windows上以管理员身份运行Java应用程序

在Windows上以管理员身份运行Java应用程序

问题描述:

我正在用Java编写一个安装程序,因此需要提升权限才能访问Program Files目录。根据我在网上找到的信息,我编写了如下实现:

I am writing an installer in Java that will accordingly require elevated privileges to access the Program Files directory. Based on information that I've found online, I've written an implementation as follows:

public static void main(String args[]) {
    if (!checkPrivileges()) { // spawn a copy w/ elevated privileges
        Runtime runtime = Runtime.getRuntime();
        try {
            Process p = runtime.exec(
                "runas /profile /user:Administrator \"java -cp . main.Main\"");
        } catch (IOException e) { ... }
    } else {
        // Run with elevated privileges
    }
}

我用来检查权限的测试会从找到的答案稍微修改 here ,如下所示:

The test that I'm using to check for privileges is modified slightly from an answer found here and looks like this:

private static boolean checkPrivileges() {
    File testPriv = new File("C:\\Program Files\\");
    if (!testPriv.canWrite()) return false;
    File fileTest = null;
    try {
        fileTest = File.createTempFile("test", ".dll", testPriv);
    } catch (IOException e) {
        return false;
    } finally {
        if (fileTest != null)
            fileTest.delete();
    }
    return true;
}

当我运行它时,它没有通过特权测试 - 正如预期的那样 - 并打电话给执行官。通过查看 p.isAlive()来检查呼叫是否有效,表明该进程实际上是活动的;但是,我没有看到任何新进程的证据,Windows也没有提示我授予权限。

When I run this, it fails the privileges test--as expected--and makes the call to exec. Checking if the call worked by looking at p.isAlive() shows that the process is, in fact, alive; however, I'm not seeing any evidence of the new process and Windows isn't prompting me to grant permissions.

我不熟悉使用 exec()在Java中,所以我很可能以某种方式误解了它的用法。就此而言,我试图在这里做甚么可能吗?如果没有,是否有一个直接的选择,实际上会得到我正在寻找的结果?

I'm not familiar with using exec() in Java, so it's quite possible that I've misunderstood its usage somehow. For that matter, is what I'm attempting to do here even possible? If not, is there a straightforward alternative that will actually get me the results that I'm looking for?

好的,我我终于设法找到了这个问题的解决方案,我很满意;它有点丑陋,但它适用于我正在做的事情。

Okay, I've finally managed to get a solution for this problem that I'm happy with; it's a bit on the ugly side, but it works for what I'm doing.

我从这个答案来做实际的特权提升;从那里,问题是实际上使用Java的解决方案之一。代码最终看起来像这样:

I borrowed the code from this answer to do the actual privilege elevation; from there, the question was one of actually getting that solution to work with Java. The code for that ends up looking like this:

    if (!checkPrivileges()) {
        try {
            String jarPath = DownloaderMain.class.getProtectionDomain().getCodeSource().getLocation().getPath();
            String decodedPath = URLDecoder.decode(jarPath, "UTF-8");
            decodedPath = decodedPath.substring(1, decodedPath.length());
            Elevator.executeAsAdministrator(System.getProperty("java.home") + "\\bin\\java", "-jar " + "\"" + decodedPath + "\"");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    } else {
        // Run with elevated privileges
    }

checkPrivileges 方法与上面没有变化, Elevator 类几乎与那个类相同出现在链接的解决方案中(我刚刚拿出了不需要的 main 方法)。该解决方案假设要升高的过程是一个罐子;为了满足您的个人需求,改变它应该不会太难。

The checkPrivileges method is unchanged from above and the Elevator class is virtually identical to the one that appears in the linked solution (I just took out the unneeded main method). This solution assumes that the process to be elevated is a jar; it shouldn't be too difficult to change this around to suit your individual needs.