Java可以启动Windows UAC吗?

Ord*_*iel 5 java uac access-control

正如标题所说,我想知道用Java(并且只有java)编写的程序是否有可能以管理员权限重新启动自己(最好是.jar),以本机Windows UAC的方式显示(为了制作它对用户来说更可靠),我完成了我的作业,并发现使用c ++和java之间的桥梁可以实现这一点,但我真的很想将它作为一个纯java项目来实现.

PS:在远程情况下,这个结果是不可能的,有人可以用另一种语言向我展示"简单"的方法(我的意思是,我找到了教程,但是我认为它不应该复杂化那么复杂).

P.S2:如果可以实现这一点,它是否可以在其他平台上运行(OS X,Linux)

Dav*_*amp 8

它不能在纯java中完成.

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

@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
Run Code Online (Sandbox Code Playgroud)

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

然后,您可以使用Runtime或从应用程序执行此操作ProcessBuilder并退出应用程序(System.exit(0);).

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

这是我做的一个例子(这必须在编译为Jar时运行,否则它将不起作用):

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\r\n"
                        + "@echo args = Right(\"%*\", (Len(\"%*\") - Len(\"%1\"))) >> %temp%\\sudo.tmp.vbs\r\n"
                        + "@echo objShell.ShellExecute \"%1\", args, \"\", \"runas\" >> %temp%\\sudo.tmp.vbs\r\n"
                        + "@cscript %temp%\\sudo.tmp.vbs\r\n"
                        + "del /f %temp%\\sudo.tmp.vbs\r\n");
            }
        } catch (IOException ex) {
            //ex.printStackTrace();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)