Windows上的Java:测试Java应用程序是否作为提升的进程运行(具有管理员权限)

tba*_*ker 5 java windows privileges administrator eclipse-rcp

情况

我有一个(基于Eclipse RCP)Java应用程序在多个平台上运行.除了Windows之外,我在所有平台上都弄明白了.

安装程序:我的应用程序安装程序始终以提升模式运行,因此可以将应用程序安装到C:\Program files\MyProduct.从用户角度来看,这意味着安装程序只能由管理员执行,UAC将要求确认.这很好用.

正常使用:普通用户可以启动应用程序.不需要管理员权限.这很好用.

自动更新:自动更新功能也会写入C:\Program Files\MyProduct,因此也需要管理员权限.这就是为什么应用程序虽然可以作为普通应用程序启动,但必须作为升级过程运行以自动更新.从用户的角度来看,它应该是" 以管理员身份运行 "来自动更新.

我想进行运行时检查以查看我的Java进程是否处于提升模式(即查看它是否是' 以管理员身份运行 '.

请注意,它可能是仅限Windows的解决方案.使用Java反射API,我可以在运行时检查Windows和/或特定于实现的类.

研究

我只在StackOverflow上找到了这个问题: 检测Java应用程序是否作为Windows管理员运行

但是,该解决方案将返回活动用户是否为Administrator组的成员.用户可能仍然以非提升模式启动我的应用程序.我已经证实了这一点.

注意

我知道Eclipse RCP应用程序会在用户目录中自动安装更新,当他或她没有管理员权限时,我想阻止这种情况.

我想允许特定于用户的配置(工作正常),但允许用户特定的更新将在卸载后留下太多混乱.

Sim*_*ane 5

使用JNAWin32 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();
   }
}
Run Code Online (Sandbox Code Playgroud)

根据 MS 文档,IsUserAnAdmin() 在 Windows 的未来版本中可能不存在。因此,更好的方法是使用 JNA 调用CheckTokenMembership 函数。然而,这样做比较复杂,所以上面的代码就是我今天使用的。


gre*_*449 3

这是 EclipseLocationManager确定是否可以写入安装目录的操作:

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

注意创建 dll 的尝试