Java可以启动Windows UAC吗?



正如标题所说,我想知道是否有可能在Java(和仅Java )中编写的程序重新启动自己(最好是.jar)具有管理员特权,以本机Windows UAC的方式显示(为了使用户更具可信赖的方式),我做了我的作业,发现可以使用C 和Java之间的桥梁来完成此操作,但是我会真的很喜欢作为一个纯Java项目。

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

p.s2:如果有可能完成此操作,它是否可以在其他平台(OS X,Linux)

上使用

不能在纯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

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

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

您应该在您的应用程序中添加立即的启动检查,以检查程序是否具有高程,如果不重新运行批处理并退出。

这是我做的示例(必须在编译为罐子或无法工作时运行):

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

使用批处理文件和 runas命令。

我怀疑"只有java"。充其量您必须在MSFT模块周围有一个JNI包装器。除非仅使用ProcessBuilder调用EXE为" Only Java",否则您的代码添加用户控制台仅是Java,而不是它调用的代码。IOW,Win不带Java API

要重新启动应用程序,您必须从Windows API调用ShellExecuteShellExecuteEx函数,然后使用runas动词。

您可以在JNA库中使用这些API。

要重新启动,您必须知道通往java.exejavaw.exe的完整路径,即命令行参数(类路径,如果有的话,以及通往JAR的路径)。显然,您可以使用Windows API获取此信息。


远程情况是什么意思?
您不能以这种方式启动远程提升过程。

您可以从网络共享中重新发布应用程序。但是它无法与映射的驱动器一起使用:高程无法访问用户的映射驱动器。


不,这不能在其他平台上使用。UAC是Windows功能。在某些方面,它类似于Linux中的sudo,因此对于Linux,您可以使用sudo $pathtojava/java.exe <yourparameters>。但是,如果您的应用程序未从控制台启动,则不会很好地工作。窗口管理器通常具有包装器,这些包装器在GUI对话框中提示密码。

只需用hackaprofaw(v29)执行此操作即可。它还于2002年发行,并于1997年开始开发。在2021年,它的版本29.10.7但是 -

if raw ram = 0
 disable "featureII" program = "JAVA(math = any)"
run on "Hackaprofaw (math = v29(x))
when "featureII" disabled
 end

相关内容

最新更新