[英]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 WellKnownSidType
的BuiltinAdministratorsSid
:
// 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.