[英]Java on Windows: Test if a Java application is run as an elevated process (with Administrator privileges)
Situation 情况
I have an (Eclipse RCP-based) Java application running on multiple platforms. 我有一个在多个平台上运行的(基于Eclipse RCP的)Java应用程序。 I got this figured out on all platforms except Windows.
我在Windows以外的所有平台上都发现了这个问题。
Installer : My application installer is always run in elevated mode, so it can install the application to C:\\Program files\\MyProduct
. 安装程序 :我的应用程序安装程序始终以提升模式运行,因此可以将应用程序安装到
C:\\Program files\\MyProduct
。 From a user perspective, this means the installer can only be executed by an Administrator and the UAC will ask for confirmation. 从用户的角度来看,这意味着安装程序只能由管理员执行,并且UAC会要求您进行确认。 This works fine.
这很好。
Normal usage : The application can be launched by normal users . 正常使用 : 普通用户可以启动该应用程序。 No administrator privileges should be required.
无需管理员权限。 This works fine.
这很好。
Auto-update : The auto-update functionality also writes to C:\\Program Files\\MyProduct
and therefore also requires administrator privileges . 自动更新 : 自动更新功能还会写入
C:\\Program Files\\MyProduct
,因此也需要管理员权限 。 That's why the application, while it can be launched as a normal application too, MUST be run as an elevated process to auto-update. 这就是为什么该应用程序虽然也可以作为普通应用程序启动,但必须作为提升过程来运行以自动更新。 From a user perspective, it should be ' Run as administrator ' to auto-update.
从用户角度来看,应以“ 以管理员身份运行 ”才能自动更新。
Question 题
I would like a runtime check to see if my Java process is in elevated mode (ie to see if it was ' Run as administrator '. 我希望运行时检查以查看我的Java进程是否处于提升模式 (即查看它是否以“ 以管理员身份运行 ”)。
Note it may be a Windows-only solution. 请注意,这可能是仅Windows的解决方案。 Using the Java reflection API, I can check for the Windows- and/or implementation-specific classes at runtime.
使用Java反射API,我可以在运行时检查Windows和/或实现特定的类。
Research 研究
I only found this question on StackOverflow: Detect if Java application was run as a Windows admin 我仅在StackOverflow上发现此问题: 检测Java应用程序是否以Windows管理员身份运行
However, that solution returns whether the active user is a member of the Administrator group. 但是,该解决方案将返回活动用户是否是Administrator组的成员。 The user may still have my application launched in non-elevated mode.
用户可能仍以非提升模式启动我的应用程序。 I have verified this.
我已经证实了这一点。
Note 注意
I know that an Eclipse RCP application will automatically install updates in the user directory, when he or she has no administrator privileges, but I want to block that case. 我知道当Eclipse RCP应用程序没有管理员权限时,它将自动在用户目录中安装更新,但是我想阻止这种情况。
I want to allow user-specific configuration (which works fine), but allowing user-specific updates would leave too much mess after uninstallation. 我想允许用户特定的配置(效果很好),但是允许用户特定的更新在卸载后会造成太多混乱。
This is what the Eclipse LocationManager
does to determine if it can write to the install directory: 这是Eclipse
LocationManager
确定它是否可以写入安装目录的操作:
public static boolean canWrite(File installDir) {
if (installDir.canWrite() == false)
return false;
if (!installDir.isDirectory())
return false;
File fileTest = null;
try {
// we use the .dll suffix to properly test on Vista virtual directories
// on Vista you are not allowed to write executable files on virtual directories like "Program Files"
fileTest = File.createTempFile("writtableArea", ".dll", installDir);
} catch (IOException e) {
//If an exception occured while trying to create the file, it means that it is not writable
return false;
} finally {
if (fileTest != null)
fileTest.delete();
}
return true;
}
Note the attempt to create a dll 注意创建dll的尝试
Using JNA and the Win32 IsUserAnAdmin function : 使用JNA和Win32 IsUserAnAdmin函数 :
import com.sun.jna.LastErrorException;
import com.sun.jna.Native;
import com.sun.jna.Platform;
import com.sun.jna.win32.StdCallLibrary;
public class WindowsAdminUtil {
public interface Shell32 extends StdCallLibrary {
boolean IsUserAnAdmin() throws LastErrorException;
}
public static final Shell32 INSTANCE =
Platform.isWindows() ?
(Shell32) Native.loadLibrary("shell32", Shell32.class) : null;
public static boolean isUserWindowsAdmin() {
return INSTANCE != null && INSTANCE.IsUserAnAdmin();
}
}
According to the MS docs, IsUserAnAdmin() might not exist in future versions of Windows. 根据MS文档,IsUserAnAdmin()在Windows的未来版本中可能不存在。 So an even better method would be to use JNA to call the CheckTokenMembership function .
因此,更好的方法是使用JNA调用CheckTokenMembership函数 。 However, doing that is more complex, so the above code is what I am using today.
但是,这样做比较复杂,因此上面的代码就是我今天使用的代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.