简体   繁体   中英

Run Java application as administrator on Windows

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
    }
}

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;
}

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.

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.

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
    }

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.

I think that the best approach to achieve this is to use the tools that microsoft built for developers since you can't do it in simple Java. In this case use a manifest file http://msdn.microsoft.com/en-us/library/aa375632(v=vs.85).aspx Just build the wrapper .exe that asks for this privileges and then spawns your java program.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM