Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. I got this figured out on all platforms except Windows.

Installer: My application installer is always run in elevated mode, so it can install the application to 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. 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. 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 (i.e. to see if it was 'Run as administrator'.

Note it may be a Windows-only solution. Using the Java reflection API, I can check for the Windows- and/or implementation-specific classes at runtime.

Research

I only found this question on StackOverflow: Detect if Java application was run as a Windows admin

However, that solution returns whether the active user is a member of the Administrator group. 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.

I want to allow user-specific configuration (which works fine), but allowing user-specific updates would leave too much mess after uninstallation.

like image 949
tbacker Avatar asked Sep 05 '13 08:09

tbacker


People also ask

How to determine if an app or process is running as administrator?

This tutorial will show you how to determine if an app or process is running as administrator (elevated) or not in Windows 10. 1. Open Task Manager in more details view. 2. Click/tap on the Details tab, right click on the column header bar, and click/tap on Select columns. (see screenshot below)

Why can’t I run the Java application?

Ensure that the Java security level is not preventing the application from running. The default security level may restrict the ability to run applications that may present a risk to your computer. How can I run the applications blocked by Security settings?

How do I check if my application is running with elevated permissions?

To check if your application is currently running with elevated permissions, you simply need to see if the current user belongs to the Administrator user group.

How to run a Java program in Windows 10?

How to run a Java program in Windows 10. To run a java program in Windows 10, we need first to install Java and then set up the environment variables. To do this, follow the following steps-How to install Java? Step 1) Visit the oracle website and then click on download. Step 2) Now, on the next page, click on Accept License Agreement and ...


2 Answers

This is what the Eclipse LocationManager does to determine if it can write to the install directory:

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

like image 134
greg-449 Avatar answered Sep 21 '22 21:09

greg-449


Using JNA and the Win32 IsUserAnAdmin function:

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. So an even better method would be to use JNA to call the CheckTokenMembership function. However, doing that is more complex, so the above code is what I am using today.

like image 34
Simon Kissane Avatar answered Sep 23 '22 21:09

Simon Kissane