Java可以启动Windows UAC吗?

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

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

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 临时目录中的something.bat (因为我们可以访问它)。

然后,您可以使用RuntimeProcessBuilder从应用程序执行此操作并退出应用程序( 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(); } } } 

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

我怀疑“只有Java”。 最好你必须在MSFT模块周围有一个JNI包装器。 除非仅使用ProcessBuilder调用exe计为“仅Java” – 否则启动用户控制台的代码将只是Java,而不是它调用的内容。 IOW,Win没有附带Java API

要重新启动升级的应用程序,必须从Windows API调用ShellExecuteShellExecuteEx函数并使用runas谓词。

您可以在带有JNA库的纯Java中使用这些API。

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


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

您可以重新启动从网络共享提升的应用程序。 然而,它不适用于映射驱动器:在提升之后,无法访问用户的映射驱动器。


不,这不适用于其他平台。 UAC是Windows的一项function。 它在某些方面类似于Linux中的sudo ,因此对于Linux,您可以使用sudo $pathtojava/java.exe 。 但是,如果您的应用程序不是从控制台启动的,那么这将无法正常工作。 窗口管理器通常具有在GUI对话框中提示输入密码的包装器。