簡體   English   中英

如何判斷我的進程是否以管理員身份運行?

[英]How can I tell if my process is running as Administrator?

我想在進程以管理員身份運行時顯示一些額外的 UI 元素,而不是在進程以管理員身份運行時,這類似於 Visual Studio 2008 在以管理員身份運行時在其標題欄中顯示“管理員”的方式。 我怎么知道?

從技術上講,如果要查看成員是否為本地管理員帳戶,則可以通過WindowsIdentity上的User屬性獲取當前用戶的安全標識符 (SID) ,如下所示(靜態GetCurrent方法獲取當前 Windows用戶):

WindowsIdentity windowsIdentity = WindowsIdentity.GetCurrent();

string sid = windowsIdentity.User.ToString();

User屬性返回User的 SID,該 SID為各種組和用戶提供了許多預定義的值

然后您將檢查SID 是否具有以下模式,表明它是本地管理員帳戶(這是一個眾所周知的 SID)

S-1-5- {其他 SID 部件} -500

或者,如果您不想解析字符串,可以使用SecurityIdentifier類:

// Get the built-in administrator account.
var sid = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, 
    null);

// Compare to the current user.
bool isBuiltInAdmin = (windowsIdentity.User == sid);

但是,我懷疑您真正想知道的是當前用戶是否是本地計算機管理員的成員。 您可以使用得到這個SID WellKnownSidTypeBuiltinAdministratorsSid

// Get the SID of the admin group on the local machine.
var localAdminGroupSid = new SecurityIdentifier(
    WellKnownSidType.BuiltinAdministratorsSid, null);

然后,您可以檢查用戶的WindowsIdentity上的Groups屬性,以查看該用戶是否是本地管理員組的成員,如下所示:

bool isLocalAdmin = windowsIdentity.Groups.
    Select(g => (SecurityIdentifier) g.Translate(typeof(SecurityIdentifier))).
    Any(s => s == localAdminGroupSid);

我認為這是一個很好的簡單機制。

using System.Security.Principal;

WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
bool isAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);

這是一個單班輪來做到這一點。

using System.Security.Principal;

static bool IsElevated => new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);

我覺得重要的是要注意根據上面 casperOne 的答案嘗試使用 WellKnownSidType.BuiltinAdministratorsSid 時遇到的困難。 根據 WellKnownSiDType MSDN ,BuiltinAdministratorsSid“表示與管理員帳戶匹配的 SID。” 所以我希望 casperOne 的代碼能夠工作,並且猜測它可能在某些環境中工作。 不幸的是,它在我的帶有 .NET 2.0(舊代碼)的 Windows 2003 上沒有。 它實際上返回了 S-1-5-32-544,根據本文,它是 Administrators的 sid。 因此,比較對我來說失敗了。 我將不得不對startswith“S-1-5-21”(即kb 243330表示包括“21”,即使上面引用的博客沒有)進行自己的字符串比較,並以“500”結尾。

我希望你解決了它,我正在尋找聰明的人來解決我的 NamedPipe 權限問題,也許 2022 年有人喜歡我對你 13 歲問題的回答......

使用 .net 6.0 > win7 或更高版本...

也許做這樣的事情並測試您看到的內容是否對您的帳戶有意義:

var user = WindowsIdentity.GetCurrent();
if (user is not null)
{

    logger.LogInformation("{User}", user.Name);
    foreach (var item in Enum.GetValues<WellKnownSidType>())
    {
        try
        {
            var sid = new SecurityIdentifier(item, user.Owner);
            logger.LogInformation($"IsIsWellKnown({item}): {user.Claims.Any(a=> a.Value == sid.Value)}");
        }
        catch { }
    }
}

那么如果可以的話,你可以使用這樣的東西:

public static bool Is(WindowsIdentity user, WellKnownSidType type)
{
    var sid = new SecurityIdentifier(type, user.Owner);
    return user.Claims.Any(a => a.Value == sid.Value);
}

您可能真的很聰明,並通過添加this關鍵字來創建擴展方法

public static bool Is(this WindowsIdentity user, WellKnownSidType type)
{
    var sid = new SecurityIdentifier(type, user.Owner);
    return user.Claims.Any(a => a.Value == sid.Value);
}

然后你可以像這樣使用它:

WindowsIdentity.GetCurrent().Is(WellKnownSidType.AccountDomainAdminsSid))

我使用簡單的 try catch 語句在“C:\\Windows\\”文件夾中創建一個隨機文件。 如果出錯,則應用程序以普通權限運行,否則以管理員權限運行。

        try
        {
            File.Create(string.Format(@"C:\Windows\{0}.txt", new Guid()), 0, FileOptions.DeleteOnClose);
            // Do as admin
        }
        catch
        {
            // Do as default
        }

暫無
暫無

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

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