正如标题所说,我想知道是否有可能在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
(因为我们可以访问此)。
然后,您将使用Runtime
或ProcessBuilder
从应用程序执行此操作,然后退出您的应用程序(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调用ShellExecute
或ShellExecuteEx
函数,然后使用runas
动词。
您可以在JNA库中使用这些API。
要重新启动,您必须知道通往java.exe
或javaw.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