簡體   English   中英

Windows上的Java:測試Java應用程序是否作為提升的進程運行(具有管理員權限)

[英]Java on Windows: Test if a Java application is run as an elevated process (with Administrator privileges)

情況

我有一個在多個平台上運行的(基於Eclipse RCP的)Java應用程序。 我在Windows以外的所有平台上都發現了這個問題。

安裝程序 :我的應用程序安裝程序始終以提升模式運行,因此可以將應用程序安裝到C:\\Program files\\MyProduct 從用戶的角度來看,這意味着安裝程序只能由管理員執行,並且UAC會要求您進行確認。 這很好。

正常使用普通用戶可以啟動該應用程序。 無需管理員權限。 這很好。

自動更新自動更新功能還會寫入C:\\Program Files\\MyProduct ,因此也需要管理員權限 這就是為什么該應用程序雖然也可以作為普通應用程序啟動,但必須作為提升過程來運行以自動更新。 從用戶角度來看,應以“ 以管理員身份運行 ”才能自動更新。

我希望運行時檢查以查看我的Java進程是否處於提升模式 (即查看它是否以“ 以管理員身份運行 ”)。

請注意,這可能是僅Windows的解決方案。 使用Java反射API,我可以在運行時檢查Windows和/或實現特定的類。

研究

我僅在StackOverflow上發現此問題: 檢測Java應用程序是否以Windows管理員身份運行

但是,該解決方案將返回活動用戶是否是Administrator組的成員。 用戶可能仍以非提升模式啟動我的應用程序。 我已經證實了這一點。

注意

我知道當Eclipse RCP應用程序沒有管理員權限時,它將自動在用戶目錄中安裝更新,但是我想阻止這種情況。

我想允許用戶特定的配置(效果很好),但是允許用戶特定的更新在卸載后會造成太多混亂。

這是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;
}

注意創建dll的嘗試

使用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();
   }
}

根據MS文檔,IsUserAnAdmin()在Windows的未來版本中可能不存在。 因此,更好的方法是使用JNA調用CheckTokenMembership函數 但是,這樣做比較復雜,因此上面的代碼就是我今天使用的代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM