不确定最佳实践,但如果您想通过其帐户在管理员组中或者他们是否有能力通过 UAC 升级到该角色来检测用户是否具有管理员权限,请查看 MSDN 代码示例自我升级:http ://code.msdn.microsoft.com/windowsdesktop/CSUACSelfElevation-644673d3/sourcecode?fileId=21729&pathId=1041468146
该示例有一个 MainForm.IsUserInAdminGroup() 方法,它查看当前用户的令牌或其升级令牌:
/// <summary>
/// The function checks whether the primary access token of the process belongs
/// to user account that is a member of the local Administrators group, even if
/// it currently is not elevated.
/// </summary>
/// <returns>
/// Returns true if the primary access token of the process belongs to user
/// account that is a member of the local Administrators group. Returns false
/// if the token does not.
/// </returns>
/// <exception cref="System.ComponentModel.Win32Exception">
/// When any native Windows API call fails, the function throws a Win32Exception
/// with the last error code.
/// </exception>
internal bool IsUserInAdminGroup()
{
bool fInAdminGroup = false;
SafeTokenHandle hToken = null;
SafeTokenHandle hTokenToCheck = null;
IntPtr pElevationType = IntPtr.Zero;
IntPtr pLinkedToken = IntPtr.Zero;
int cbSize = 0;
try
{
// Open the access token of the current process for query and duplicate.
if (!NativeMethods.OpenProcessToken(Process.GetCurrentProcess().Handle,
NativeMethods.TOKEN_QUERY | NativeMethods.TOKEN_DUPLICATE, out hToken))
{
throw new Win32Exception();
}
// Determine whether system is running Windows Vista or later operating
// systems (major version >= 6) because they support linked tokens, but
// previous versions (major version < 6) do not.
if (Environment.OSVersion.Version.Major >= 6)
{
// Running Windows Vista or later (major version >= 6).
// Determine token type: limited, elevated, or default.
// Allocate a buffer for the elevation type information.
cbSize = sizeof(TOKEN_ELEVATION_TYPE);
pElevationType = Marshal.AllocHGlobal(cbSize);
if (pElevationType == IntPtr.Zero)
{
throw new Win32Exception();
}
// Retrieve token elevation type information.
if (!NativeMethods.GetTokenInformation(hToken,
TOKEN_INFORMATION_CLASS.TokenElevationType, pElevationType,
cbSize, out cbSize))
{
throw new Win32Exception();
}
// Marshal the TOKEN_ELEVATION_TYPE enum from native to .NET.
TOKEN_ELEVATION_TYPE elevType = (TOKEN_ELEVATION_TYPE)
Marshal.ReadInt32(pElevationType);
// If limited, get the linked elevated token for further check.
if (elevType == TOKEN_ELEVATION_TYPE.TokenElevationTypeLimited)
{
// Allocate a buffer for the linked token.
cbSize = IntPtr.Size;
pLinkedToken = Marshal.AllocHGlobal(cbSize);
if (pLinkedToken == IntPtr.Zero)
{
throw new Win32Exception();
}
// Get the linked token.
if (!NativeMethods.GetTokenInformation(hToken,
TOKEN_INFORMATION_CLASS.TokenLinkedToken, pLinkedToken,
cbSize, out cbSize))
{
throw new Win32Exception();
}
// Marshal the linked token value from native to .NET.
IntPtr hLinkedToken = Marshal.ReadIntPtr(pLinkedToken);
hTokenToCheck = new SafeTokenHandle(hLinkedToken);
}
}
// CheckTokenMembership requires an impersonation token. If we just got
// a linked token, it already is an impersonation token. If we did not
// get a linked token, duplicate the original into an impersonation
// token for CheckTokenMembership.
if (hTokenToCheck == null)
{
if (!NativeMethods.DuplicateToken(hToken,
SECURITY_IMPERSONATION_LEVEL.SecurityIdentification,
out hTokenToCheck))
{
throw new Win32Exception();
}
}
// Check if the token to be checked contains admin SID.
WindowsIdentity id = new WindowsIdentity(hTokenToCheck.DangerousGetHandle());
WindowsPrincipal principal = new WindowsPrincipal(id);
fInAdminGroup = principal.IsInRole(WindowsBuiltInRole.Administrator);
}
finally
{
// Centralized cleanup for all allocated resources.
if (hToken != null)
{
hToken.Close();
hToken = null;
}
if (hTokenToCheck != null)
{
hTokenToCheck.Close();
hTokenToCheck = null;
}
if (pElevationType != IntPtr.Zero)
{
Marshal.FreeHGlobal(pElevationType);
pElevationType = IntPtr.Zero;
}
if (pLinkedToken != IntPtr.Zero)
{
Marshal.FreeHGlobal(pLinkedToken);
pLinkedToken = IntPtr.Zero;
}
}
return fInAdminGroup;
}