Попробуйте это:
using Microsoft.Win32;
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security.Principal;
public static class UacHelper
{
private const string uacRegistryKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
private const string uacRegistryValue = "EnableLUA";
private static uint STANDARD_RIGHTS_READ = 0x00020000;
private static uint TOKEN_QUERY = 0x0008;
private static uint TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY);
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool GetTokenInformation(IntPtr TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, IntPtr TokenInformation, uint TokenInformationLength, out uint ReturnLength);
public enum TOKEN_INFORMATION_CLASS
{
TokenUser = 1,
TokenGroups,
TokenPrivileges,
TokenOwner,
TokenPrimaryGroup,
TokenDefaultDacl,
TokenSource,
TokenType,
TokenImpersonationLevel,
TokenStatistics,
TokenRestrictedSids,
TokenSessionId,
TokenGroupsAndPrivileges,
TokenSessionReference,
TokenSandBoxInert,
TokenAuditPolicy,
TokenOrigin,
TokenElevationType,
TokenLinkedToken,
TokenElevation,
TokenHasRestrictions,
TokenAccessInformation,
TokenVirtualizationAllowed,
TokenVirtualizationEnabled,
TokenIntegrityLevel,
TokenUIAccess,
TokenMandatoryPolicy,
TokenLogonSid,
MaxTokenInfoClass
}
public enum TOKEN_ELEVATION_TYPE
{
TokenElevationTypeDefault = 1,
TokenElevationTypeFull,
TokenElevationTypeLimited
}
public static bool IsUacEnabled
{
get
{
RegistryKey uacKey = Registry.LocalMachine.OpenSubKey(uacRegistryKey, false);
bool result = uacKey.GetValue(uacRegistryValue).Equals(1);
return result;
}
}
public static bool IsProcessElevated
{
get
{
if (IsUacEnabled)
{
IntPtr tokenHandle;
if (!OpenProcessToken(Process.GetCurrentProcess().Handle, TOKEN_READ, out tokenHandle))
{
throw new ApplicationException("Could not get process token. Win32 Error Code: " + Marshal.GetLastWin32Error());
}
TOKEN_ELEVATION_TYPE elevationResult = TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault;
int elevationResultSize = Marshal.SizeOf((int)elevationResult);
uint returnedSize = 0;
IntPtr elevationTypePtr = Marshal.AllocHGlobal(elevationResultSize);
bool success = GetTokenInformation(tokenHandle, TOKEN_INFORMATION_CLASS.TokenElevationType, elevationTypePtr, (uint)elevationResultSize, out returnedSize);
if (success)
{
elevationResult = (TOKEN_ELEVATION_TYPE)Marshal.ReadInt32(elevationTypePtr);
bool isProcessAdmin = elevationResult == TOKEN_ELEVATION_TYPE.TokenElevationTypeFull;
return isProcessAdmin;
}
else
{
throw new ApplicationException("Unable to determine the current elevation.");
}
}
else
{
WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
bool result = principal.IsInRole(WindowsBuiltInRole.Administrator);
return result;
}
}
}
}
Marshal.SizeOf((int)elevationResult)
но я пока не знаю почему. Сообщение об исключении: Метод не найден. В:Int32 System.Runtime.InteropServices.Marshal.SizeOf(!!0).
(новый ответ через шесть лет после того, как вопрос был задан)
Отказ от ответственности: это просто то, что случилось с моей конкретной ОС с моими конкретными настройками с моим конкретным пользователем:
using System.Security.Principal; // ... static bool IsElevated { get { return WindowsIdentity.GetCurrent().Owner .IsWellKnown(WellKnownSidType.BuiltinAdministratorsSid); } }
Поэтому, когда я запускаю этот «Запуск от имени администратора»,
get
возвращается свойство доступаtrue
. При нормальной работе (даже если мой пользователь «является» администратором, но не запускает это конкретное приложение «от имени администратора»), он возвращаетсяfalse
.Это кажется намного проще, чем многие другие ответы.
Я понятия не имею, есть ли случаи, когда это не удается.
PS! Это тоже кажется нормальным:
static bool IsElevated { get { var id = WindowsIdentity.GetCurrent(); return id.Owner != id.User; } }
источник
IsElevated
он вернет false, но процесс все еще может работать с высоким уровнем целостности. Подлинно неподготовленный процесс имеет средний уровень целостности. Вероятно, это не имеет отношения к 99% приложений, но стоит упомянуть, потому что такие инструменты, как Process Hacker, могут по-прежнему объявлять такой процесс повышенным. «Полувысокий» процесс - это не то, что вы обычно видели бы; это может произойти, когда кто-то не может правильно запустить дочерний процесс, не имеющий прав.Вот модифицированная версия этого ответа, которая включает такие вещи, как правильное использование ресурсов и управление администраторами домена.
public static class UacHelper { private const string uacRegistryKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"; private const string uacRegistryValue = "EnableLUA"; private static uint STANDARD_RIGHTS_READ = 0x00020000; private static uint TOKEN_QUERY = 0x0008; private static uint TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY); [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle); [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool CloseHandle(IntPtr hObject); [DllImport("advapi32.dll", SetLastError = true)] public static extern bool GetTokenInformation(IntPtr TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, IntPtr TokenInformation, uint TokenInformationLength, out uint ReturnLength); public enum TOKEN_INFORMATION_CLASS { TokenUser = 1, TokenGroups, TokenPrivileges, TokenOwner, TokenPrimaryGroup, TokenDefaultDacl, TokenSource, TokenType, TokenImpersonationLevel, TokenStatistics, TokenRestrictedSids, TokenSessionId, TokenGroupsAndPrivileges, TokenSessionReference, TokenSandBoxInert, TokenAuditPolicy, TokenOrigin, TokenElevationType, TokenLinkedToken, TokenElevation, TokenHasRestrictions, TokenAccessInformation, TokenVirtualizationAllowed, TokenVirtualizationEnabled, TokenIntegrityLevel, TokenUIAccess, TokenMandatoryPolicy, TokenLogonSid, MaxTokenInfoClass } public enum TOKEN_ELEVATION_TYPE { TokenElevationTypeDefault = 1, TokenElevationTypeFull, TokenElevationTypeLimited } public static bool IsUacEnabled { get { using (RegistryKey uacKey = Registry.LocalMachine.OpenSubKey(uacRegistryKey, false)) { bool result = uacKey.GetValue(uacRegistryValue).Equals(1); return result; } } } public static bool IsProcessElevated { get { if (IsUacEnabled) { IntPtr tokenHandle = IntPtr.Zero; if (!OpenProcessToken(Process.GetCurrentProcess().Handle, TOKEN_READ, out tokenHandle)) { throw new ApplicationException("Could not get process token. Win32 Error Code: " + Marshal.GetLastWin32Error()); } try { TOKEN_ELEVATION_TYPE elevationResult = TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault; int elevationResultSize = Marshal.SizeOf(typeof(TOKEN_ELEVATION_TYPE)); uint returnedSize = 0; IntPtr elevationTypePtr = Marshal.AllocHGlobal(elevationResultSize); try { bool success = GetTokenInformation(tokenHandle, TOKEN_INFORMATION_CLASS.TokenElevationType, elevationTypePtr, (uint) elevationResultSize, out returnedSize); if (success) { elevationResult = (TOKEN_ELEVATION_TYPE) Marshal.ReadInt32(elevationTypePtr); bool isProcessAdmin = elevationResult == TOKEN_ELEVATION_TYPE.TokenElevationTypeFull; return isProcessAdmin; } else { throw new ApplicationException("Unable to determine the current elevation."); } } finally { if (elevationTypePtr != IntPtr.Zero) Marshal.FreeHGlobal(elevationTypePtr); } } finally { if (tokenHandle != IntPtr.Zero) CloseHandle(tokenHandle); } } else { WindowsIdentity identity = WindowsIdentity.GetCurrent(); WindowsPrincipal principal = new WindowsPrincipal(identity); bool result = principal.IsInRole(WindowsBuiltInRole.Administrator) || principal.IsInRole(0x200); //Domain Administrator return result; } } } }
источник
Marshal.SizeOf((int)elevationResult)
но я пока не знаю почему. Сообщение об исключении: Метод не найден. В:Int32 System.Runtime.InteropServices.Marshal.SizeOf(!!0).
Marshal.SizeOf(typeof(TOKEN_ELEVATION_TYPE))
,int elevationResultSize = Marshal.SizeOf(typeof(TOKEN_ELEVATION_TYPE))
бросаетArgumentException
на 32 бит приложения .NET 4.0,int elevationResultSize = Marshal.SizeOf((int)elevationResult)
работал, однако.В проекте CodePlex UAChelper есть код, который проверяет повышение прав в UserAccountControl.cpp
UserAccountControl::IsUserAdmin
, который проверяет, включен ли UAC, а затем проверяет, повышен ли процесс.bool UserAccountControl::IsCurrentProcessElevated::get() { return GetProcessTokenElevationType() == TokenElevationTypeFull; //elevated }
из функции:
int UserAccountControl::GetProcessTokenElevationType() { HANDLE hToken; try { if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) throw gcnew Win32Exception(GetLastError()); TOKEN_ELEVATION_TYPE elevationType; DWORD dwSize; if (!GetTokenInformation(hToken, TokenElevationType, &elevationType, sizeof(elevationType), &dwSize)) throw gcnew Win32Exception(GetLastError()); return elevationType; } finally { CloseHandle(hToken); } }
источник
В .net Framwork 4.5 я нашел другой метод, который мне подходит. В отношении следующего сценария, который можно найти здесь (на немецком языке)
rem --- Admintest.bat --- whoami /groups | find "S-1-5-32-544" > nul if errorlevel 1 goto ende echo Benutzer %username% ist lokaler Administrator. :ende
В C # это выглядит так:
private bool IsAdmin { get { WindowsIdentity identity = WindowsIdentity.GetCurrent(); if (identity != null) { WindowsPrincipal principal = new WindowsPrincipal(identity); List<Claim> list = new List<Claim>(principal.UserClaims); Claim c = list.Find(p => p.Value.Contains("S-1-5-32-544")); if (c != null) return true; } return false; } }
Но в .net <4.5
WindowsPrincipal
класс не содержитUserClaims
свойства, и я не нашел способа получить эту информацию.источник
private bool IsAdmin{ get { ... } }
), тогда вам не нужны скобки, если вы вызываетеIsAdmin
.Использование
TokenElevationType
будет работать, но если вы введете PInvokeCheckTokenMembership()
против SID группы администратора, ваш код также будет работать, когда UAC выключен и на 2000 / XP / 2003, а также будет обрабатывать запрещенные SID.Существует также
IsUserAnAdmin()
функция, которая выполняетCheckTokenMembership
проверку за вас, но MSDN говорит, что она может быть не навсегдаисточник
В этом ответе есть несколько проблем. Во-первых, он не получает никаких системных процессов, которые запускаются от имени администратора (например, NT-Authority / SYSTEM). Приведенный ниже пример кода устраняет все проблемы (обнаруживает, LocalAdmins, DomainAdmins и LocalSystemAdmins)
Если вам нужен только текущий процесс, замените его
pHandle
наProcess.GetCurrentProcess().Handle
internal static bool IsProcessElevatedEx(this IntPtr pHandle) { var token = IntPtr.Zero; if (!OpenProcessToken(pHandle, MAXIMUM_ALLOWED, ref token)) throw new Win32Exception(Marshal.GetLastWin32Error(), "OpenProcessToken failed"); WindowsIdentity identity = new WindowsIdentity(token); WindowsPrincipal principal = new WindowsPrincipal(identity); bool result = principal.IsInRole(WindowsBuiltInRole.Administrator) || principal.IsInRole(0x200); //Domain Administrator CloseHandle(token); return result; }
источник
Думаю, есть еще одна проблема. Я проверил предоставленные вами решения и должен сказать, что при установке Windows 7 и входе в систему как администратор проверка не работает. Windows никогда не возвращает информацию о том, что процесс работает в повышенном режиме. Итак, последовательность:
if (IsUacEnabled) return IsProcessInElevatedMode(); return IsUserAdmin();
не возвращает истину, если вы вошли в систему как администратор, но процесс имеет все привилегии для выполнения системных операций (например, остановки системных служб). Последовательность работы такова:
if (IsUserAdmin()) return true; if (IsUacEnabled) return IsProcessInElevatedMode(); return false;
Сначала вы должны проверить, запущен ли процесс в контексте администратора. Дополнительная информация:
IsUacEnabled() - checks if the UAC has been enabled in the system (Windows) IsProcessInElevatedMode() - checks if the process is run in an elevated mode IsUserAdmin() - checks if the current user has an Administrtor role
Все эти методы были описаны в предыдущих постах.
источник
Использование пакета nuget UACHelper : https://www.nuget.org/packages/UACHelper/
if (UACHelper.IsElevated) // something else // something else
Существует множество других свойств, которые можно использовать для определения того, является ли пользователь на самом деле администратором, или процесс выполняется под виртуализацией UAC, или владелец рабочего стола является владельцем процесса. (Запуск от имени ограниченной учетной записи)
Прочтите меня для получения дополнительной информации.
источник
Я использую этот код, и он хорошо работает:
bool runningAsAdmin = WindowsIdentity.GetCurrent().Owner.IsWellKnown(WellKnownSidType.BuiltinAdministratorsSid);
* Admin является частью группы встроенных администраторов.
«Учетная запись пользователя для системного администратора. Эта учетная запись - первая учетная запись, созданная во время установки операционной системы. Учетная запись не может быть удалена или заблокирована. Она является членом группы администраторов и не может быть удалена из этой группы». - https://ss64.com/nt/syntax-security_groups.html
источник