Wypróbuj to:
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)
nie jestem jeszcze pewien, dlaczego. Komunikat o wyjątku: Nie znaleziono metody. O:Int32 System.Runtime.InteropServices.Marshal.SizeOf(!!0).
(nowa odpowiedź sześć lat po zadaniu pytania)
Zastrzeżenie: to tylko coś, co działało w moim konkretnym systemie operacyjnym z moimi określonymi ustawieniami dla mojego konkretnego użytkownika:
using System.Security.Principal; // ... static bool IsElevated { get { return WindowsIdentity.GetCurrent().Owner .IsWellKnown(WellKnownSidType.BuiltinAdministratorsSid); } }
Więc kiedy uruchamiam to „Uruchom jako administrator”, metoda
get
dostępu właściwości zwracatrue
. Podczas normalnego działania (nawet jeśli mój użytkownik „jest” administratorem, po prostu nie uruchamia tej konkretnej aplikacji „jako administrator”), zwracafalse
.Wydaje się to o wiele prostsze niż wiele innych odpowiedzi.
Nie mam pojęcia, czy są przypadki, w których to się nie powiedzie.
PS! To również wydaje się OK:
static bool IsElevated { get { var id = WindowsIdentity.GetCurrent(); return id.Owner != id.User; } }
źródło
IsElevated
zwróci błąd, ale proces może nadal działać z wysokim poziomem integralności. Prawdziwie niewysoki proces ma średni poziom integralności. Prawdopodobnie nie ma to znaczenia w przypadku 99% aplikacji, ale warto o tym wspomnieć, ponieważ narzędzia takie jak Process Hacker mogą nadal deklarować podniesienie poziomu takiego procesu. Proces „częściowo niewniesiony” nie jest czymś, co można zobaczyć normalnie; może się to zdarzyć, gdy ktoś nie uruchomi poprawnie niewniesionego procesu potomnego.Oto zmodyfikowana wersja tej odpowiedzi, która obejmuje takie rzeczy, jak właściwe usuwanie zasobów i obsługa administratorów domeny.
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; } } } }
źródło
Marshal.SizeOf((int)elevationResult)
nie jestem jeszcze pewien, dlaczego. Komunikat o wyjątku: Nie znaleziono metody. O:Int32 System.Runtime.InteropServices.Marshal.SizeOf(!!0).
Marshal.SizeOf(typeof(TOKEN_ELEVATION_TYPE))
,int elevationResultSize = Marshal.SizeOf(typeof(TOKEN_ELEVATION_TYPE))
rzucaArgumentException
32-bitową aplikację .NET 4.0int elevationResultSize = Marshal.SizeOf((int)elevationResult)
, jednak zadziałała.Projekt CodePlex UAChelper ma kod, który sprawdza podniesienie uprawnień w UserAccountControl.cpp
UserAccountControl::IsUserAdmin
, który sprawdza, czy UAC jest włączony, a następnie sprawdza, czy proces jest podniesiony.bool UserAccountControl::IsCurrentProcessElevated::get() { return GetProcessTokenElevationType() == TokenElevationTypeFull; //elevated }
z funkcji:
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); } }
źródło
W .net Framwork 4.5 znalazłem inną metodę, która działa dla mnie. W związku z następującym skryptem, który można znaleźć tutaj (w języku niemieckim)
rem --- Admintest.bat --- whoami /groups | find "S-1-5-32-544" > nul if errorlevel 1 goto ende echo Benutzer %username% ist lokaler Administrator. :ende
W C # wygląda to tak:
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; } }
Ale w .net <4.5
WindowsPrincipal
klasa nie zawieraUserClaims
właściwości i nie znalazłem sposobu na uzyskanie tych informacji.źródło
private bool IsAdmin{ get { ... } }
), więc nie potrzebujesz nawiasów, jeśli wywołaszIsAdmin
.Używanie
TokenElevationType
mogłoby zadziałać, ale jeśli użyjesz PInvokeCheckTokenMembership()
przeciwko identyfikatorowi SID grupy administratorów, twój kod będzie działał również, gdy UAC jest wyłączony i na 2000 / XP / 2003, a także będzie obsługiwał odmowy identyfikatorów SID.Istnieje również
IsUserAnAdmin()
funkcja, któraCheckTokenMembership
sprawdza za Ciebie, ale MSDN twierdzi, że może nie istnieć na zawszeźródło
Ta odpowiedź ma kilka problemów. Po pierwsze, nie pobiera żadnych procesów systemowych działających jako administrator (na przykład w ramach NT-Authority / SYSTEM). Poniższy przykład kodu rozwiązuje wszystkie problemy (wykrywa, LocalAdmins, DomainAdmins i LocalSystemAdmins)
Jeśli chcesz po prostu bieżącego procesu, wymienić
pHandle
zProcess.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; }
źródło
Myślę, że jest jeszcze jeden problem. Sprawdziłem dostarczone przez Ciebie rozwiązania i muszę powiedzieć, że przy instalacji Windows 7 i zalogowałem się jako administrator sprawdzanie nie działa. System Windows nigdy nie zwraca informacji, że proces działa w trybie podwyższonym. A więc sekwencja:
if (IsUacEnabled) return IsProcessInElevatedMode(); return IsUserAdmin();
nie zwraca prawdy, gdy jest zalogowany jako Administrator, ale proces ma wszystkie uprawnienia do wykonywania operacji systemowych (np. zatrzymywania usług systemowych). Sekwencja robocza to:
if (IsUserAdmin()) return true; if (IsUacEnabled) return IsProcessInElevatedMode(); return false;
Najpierw sprawdź, czy proces jest uruchamiany w kontekście administratora. Dodatkowe informacje:
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
Wszystkie te metody zostały opisane w poprzednich postach.
źródło
Korzystanie z pakietu NuGet UACHelper : https://www.nuget.org/packages/UACHelper/
if (UACHelper.IsElevated) // something else // something else
Istnieje wiele innych właściwości, których można użyć do wykrycia, czy użytkownik jest w rzeczywistości administratorem, czy proces działa w ramach wirtualizacji UAC, lub czy właściciel pulpitu jest właścicielem procesu. (Uruchom jak z ograniczonego konta)
Sprawdź przeczytaj mnie, aby uzyskać więcej informacji.
źródło
Używam tego kodu i działa dobrze:
bool runningAsAdmin = WindowsIdentity.GetCurrent().Owner.IsWellKnown(WellKnownSidType.BuiltinAdministratorsSid);
* Admin jest częścią grupy Build-In Administrators.
„Konto użytkownika dla administratora systemu. To konto jest pierwszym kontem utworzonym podczas instalacji systemu operacyjnego. Konto nie może zostać usunięte ani zablokowane. Jest członkiem grupy Administratorzy i nie można go usunąć z tej grupy”. - https://ss64.com/nt/syntax-security_groups.html
źródło