由于Win7引入了UAC,所以在管理员账户下,双击程序启动,在没有弹出UAC窗口情况下,虽然是以管理员身份启动了进程,但是并没有获取到相应的privileges。
下面这个例子展示了在UAC开启状态下,两种不同打开方式运行的效果。
static void Main(string[] args) { Console.WriteLine("Checking elevated"); Console.WriteLine("UAC enable : " + UacHelper.IsUacEnabled); Console.WriteLine("IsProcessElevated : " + UacHelper.IsProcessElevated); Console.ReadLine(); }
在下图这种方式下,获取到的Token中ElevationType是TokenElevationTypeLimited

1双击运行
ElevationType是TokenElevationTypeFull

2右键管理员运行
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; } } } }
Windows AccessToken 访问模型详见 https://msdn.microsoft.com/en-us/library/windows/desktop/aa374862(v=vs.85).aspx
浙公网安备 33010602011771号