Created
October 3, 2015 06:14
-
-
Save lextm/e966ca6bbf44403d906b to your computer and use it in GitHub Desktop.
Add/Remove shield icon to/from WinForms Button
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
// ReSharper disable InconsistentNaming | |
namespace JexusManager | |
{ | |
using System.Diagnostics; | |
using System.Runtime.InteropServices; | |
using System.Security.Principal; | |
using System.Windows.Forms; | |
using Microsoft.Win32; | |
internal static class NativeMethods | |
{ | |
[DllImport("user32")] | |
public static extern uint SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); | |
internal const int BCM_SETSHIELD = (0x1600 + 0x000C); //Elevated button | |
private static void AddShieldToButton(Button b) | |
{ | |
b.FlatStyle = FlatStyle.System; | |
SendMessage(b.Handle, BCM_SETSHIELD, IntPtr.Zero, (IntPtr)1); | |
} | |
public static void TryAddShieldToButton(Button button) | |
{ | |
if (!IsProcessElevated) | |
{ | |
AddShieldToButton(button); | |
} | |
} | |
public static void RemoveShieldFromButton(Button b) | |
{ | |
b.FlatStyle = FlatStyle.System; | |
SendMessage(b.Handle, BCM_SETSHIELD, IntPtr.Zero, (IntPtr)0); | |
} | |
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 readonly 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 | |
} | |
private static bool IsUacEnabled | |
{ | |
get | |
{ | |
RegistryKey uacKey = Registry.LocalMachine.OpenSubKey(uacRegistryKey, false); | |
bool result = uacKey != null && 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; | |
} | |
throw new ApplicationException("Unable to determine the current elevation."); | |
} | |
WindowsIdentity identity = WindowsIdentity.GetCurrent(); | |
WindowsPrincipal principal = new WindowsPrincipal(identity); | |
bool result = principal.IsInRole(WindowsBuiltInRole.Administrator); | |
return result; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Microsoft's article on the details, https://msdn.microsoft.com/en-us/library/aa361904.aspx