检测Java应用程序是否作为Windows管理员运行

use*_*041 19 java windows privileges admin

我有一个Java应用程序.无论如何,我可以判断该进程是否在Windows 7上以管理员权限运行.

MyP*_*ats 32

我找到了一个似乎与平台无关的不同解决方案.它试图编写系统偏好.如果失败,则用户可能不是管理员.

import java.io.OutputStream;
import java.io.PrintStream;
import java.util.prefs.Preferences;

import static java.lang.System.setErr;
import static java.util.prefs.Preferences.systemRoot;

public class AdministratorChecker
{
    public static final boolean IS_RUNNING_AS_ADMINISTRATOR;

    static
    {
        IS_RUNNING_AS_ADMINISTRATOR = isRunningAsAdministrator();
    }

    private static boolean isRunningAsAdministrator()
    {
        Preferences preferences = systemRoot();

        synchronized (System.err)
        {
            setErr(new PrintStream(new OutputStream()
            {
                @Override
                public void write(int b)
                {
                }
            }));

            try
            {
                preferences.put("foo", "bar"); // SecurityException on Windows
                preferences.remove("foo");
                preferences.flush(); // BackingStoreException on Linux
                return true;
            } catch (Exception exception)
            {
                return false;
            } finally
            {
                setErr(System.err);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

正如TomášZato建议的那样,您可能想要抑制由此方法引起的错误消息.您可以通过设置System.err来完成此操作:

import java.io.OutputStream;
import java.io.PrintStream;
import java.util.prefs.Preferences;

import static java.lang.System.setErr;
import static java.util.prefs.Preferences.systemRoot;

public class AdministratorChecker
{
    public static final boolean IS_RUNNING_AS_ADMINISTRATOR;

    static
    {
        IS_RUNNING_AS_ADMINISTRATOR = isRunningAsAdministrator();
    }

    private static boolean isRunningAsAdministrator()
    {
        Preferences preferences = systemRoot();

        synchronized (System.err)
        {
            setErr(new PrintStream(new OutputStream()
            {
                @Override
                public void write(int b)
                {
                }
            }));

            try
            {
                preferences.put("foo", "bar"); // SecurityException on Windows
                preferences.remove("foo");
                preferences.flush(); // BackingStoreException on Linux
                return true;
            } catch (Exception exception)
            {
                return false;
            } finally
            {
                setErr(System.err);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,由于`System.setErr(null)`,答案中的第二个代码块会抛出一个`NullPointerException`.要解决这个问题,请使用虚拟输出流:`System.setErr(new PrintStream(new OutputStream(){@Override public void write(int i)throws IOException {}});; (6认同)
  • 如果其他线程也不同步到`System.err`,则`synchronized(systemErr)`行无效. (2认同)
  • +1,因为这检测(我认为所谓的)管理上下文,而不仅仅是管理用户。我是我的电脑的管理员,但大多数时候我不运行具有管理权限的程序。为了使上述返回 true,我必须使用“以管理员身份运行”来执行我的程序,这与仅以属于管理员组的用户身份运行程序不同。 (2认同)

Cod*_*nci 20

我发现这个代码片段在线,我认为会为你完成这项工作.

public static boolean isAdmin() {
    String groups[] = (new com.sun.security.auth.module.NTSystem()).getGroupIDs();
    for (String group : groups) {
        if (group.equals("S-1-5-32-544"))
            return true;
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

它仅适用于Windows,并内置于核心Java包中.我刚刚测试了这段代码,它确实有效.它让我感到惊讶,但确实如此.

SID S-1-5-32-544是Windows操作系统中Administrator组的ID.

以下是有关其工作原理的更多详细信息的链接.

  • 请注意,此代码段会测试活动用户是否为管理员,而不是用户是否已将应用程序作为提升的进程启动! (19认同)
  • 好的'S-1-5-32-544.我应该想到这一点. (7认同)
  • 此代码可能仅适用于Oracle JRE,并且不保证可以与JRE的任何更新一起使用:http://www.oracle.com/technetwork/java/faq-sun-packages-142232.html (3认同)
  • ...并且由于私有类,仅适用于Sun JVM。 (2认同)

Tho*_*sen 5

Java运行时环境中没有这样的工具,但可能位于依赖于平台的本机例程中.请注意,通常最好的方法是确实尝试这样做,看看它是否失败.