Java 可以启动 Windows UAC 吗? [英] Can Java launch the Windows UAC?

查看:31
本文介绍了Java 可以启动 Windows UAC 吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正如标题所说,我想知道用 Java(并且只有 java)编写的程序是否有可能以管理员权限重新启动自己(最好是 .jar),显示在以原生 Windows UAC 的方式(为了使其对用户更可信),我做了功课并发现可以使用 c++ 和 java 之间的桥梁来完成此操作,但我真的很想将其作为一个纯粹的java项目.

As the title says, I'm wondering if it is possible for a program written in Java (and only java) to relaunch himself (preferably a .jar) with administrator privileges, showing in the way the native Windows UAC (in order to make it more trustable for the user), i did my homework and found out that it is possible to accomplish this using bridges between c++ and java, but i would really like to do this as a pure java project.

PS:在这种结果不可能的远程情况下,有人可以向我展示使用另一种语言执行此操作的简单"方法(我的意思是,我找到了教程,但我认为它们对于某些事情来说很复杂应该没有那么复杂).

P.S: In the remote case that this result to be impossible, can someone show me the "easy" way to do this using another language (i mean, I've found tutorials, but they are to complicated for something I think it should not be that complicated).

P.S2:如果可以做到这一点,在其他平台(OS X、Linux)上是否可行

P.S2: In case it is possible to accomplish this, would it work, on other platforms (OS X, Linux)

推荐答案

纯java做不到.

最好的办法是将其写入文件:

Best bet would be to write this to a file:

@echo Set objShell = CreateObject("Shell.Application") > %temp%sudo.tmp.vbs
@echo args = Right("%*", (Len("%*") - Len("%1"))) >> %temp%sudo.tmp.vbs
@echo objShell.ShellExecute "%1", args, "", "runas" >> %temp%sudo.tmp.vbs
@cscript %temp%sudo.tmp.vbs

并将其保存为 something.bat 在 Windows temp 目录中(因为我们可以访问它).

and save it as something.bat in Windows temp directory (as we have access to this).

然后您将使用 RuntimeProcessBuilder 从您的应用程序执行此操作并退出您的应用程序 (System.exit(0);).

You would then execute this from your application using Runtime or ProcessBuilder and exit your application (System.exit(0);).

您应该向您的应用程序添加立即启动检查,以检查程序是否已提升,如果没有重新运行批处理并退出,则程序已继续.

You should add an immediate start up check to your application that checks if the program has elevation, if it has proceed if not re-run the batch and exit.

这是我做的一个例子(这必须在编译为 Jar 时运行,否则将无法工作):

Here is an example I made (this must be run when compiled as a Jar or it wont work):

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import javax.swing.JOptionPane;

/**
 *
 * @author David
 */
public class UacTest {

    public static String jarName = "UacTest.jar", batName = "elevate.bat";

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        if (checkForUac()) {//uac is on
            JOptionPane.showMessageDialog(null, "I am not elevated");
            //attempt elevation
            new UacTest().elevate();
            System.exit(0);
        } else {//uac is not on
            //if we get here we are elevated
            JOptionPane.showMessageDialog(null, "I am elevated");
        }

    }

    private static boolean checkForUac() {
        File dummyFile = new File("c:/aaa.txt");
        dummyFile.deleteOnExit();

        try {
            //attempt to craete file in c:/
            try (FileWriter fw = new FileWriter(dummyFile, true)) {
            }
        } catch (IOException ex) {//we cannot UAC muts be on
            //ex.printStackTrace();
            return true;
        }
        return false;
    }

    private void elevate() {
        //create batch file in temporary directory as we have access to it regardless of UAC on or off
        File file = new File(System.getProperty("java.io.tmpdir") + "/" + batName);
        file.deleteOnExit();

        createBatchFile(file);

        runBatchFile();

    }

    private String getJarLocation() {
        return getClass().getProtectionDomain().getCodeSource().getLocation().getPath().substring(1);
    }

    private void runBatchFile() {
        //JOptionPane.showMessageDialog(null, getJarLocation());

        Runtime runtime = Runtime.getRuntime();
        String[] cmd = new String[]{"cmd.exe", "/C",
            System.getProperty("java.io.tmpdir") + "/" + batName + " java -jar " + getJarLocation()};
        try {
            Process proc = runtime.exec(cmd);
            //proc.waitFor();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void createBatchFile(File file) {
        try {
            try (FileWriter fw = new FileWriter(file, true)) {
                fw.write(
                        "@echo Set objShell = CreateObject("Shell.Application") > %temp%\sudo.tmp.vbs
"
                        + "@echo args = Right("%*", (Len("%*") - Len("%1"))) >> %temp%\sudo.tmp.vbs
"
                        + "@echo objShell.ShellExecute "%1", args, "", "runas" >> %temp%\sudo.tmp.vbs
"
                        + "@cscript %temp%\sudo.tmp.vbs
"
                        + "del /f %temp%\sudo.tmp.vbs
");
            }
        } catch (IOException ex) {
            //ex.printStackTrace();
        }
    }
}

这篇关于Java 可以启动 Windows UAC 吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆