現在のユーザーが管理者であるかどうか調べる方法を幾つか紹介します。なおこの記事を書くに当たり、以下のページを参考にさせていただきました。
アプリケーションを実行しているユーザーに管理者権限があるかを調べるには、以下のようにWindowsPrincipal.IsInRoleメソッドを使う方法があります。
''' <summary> ''' 現在アプリケーションを実行しているユーザーに管理者権限があるか調べる ''' </summary> ''' <returns>管理者権限がある場合はtrue。</returns> Public Shared Function IsAdministrator() As Boolean '現在のユーザーを表すWindowsIdentityオブジェクトを取得する Dim wi As System.Security.Principal.WindowsIdentity = _ System.Security.Principal.WindowsIdentity.GetCurrent() 'WindowsPrincipalオブジェクトを作成する Dim wp As New System.Security.Principal.WindowsPrincipal(wi) 'Administratorsグループに属しているか調べる Return wp.IsInRole( _ System.Security.Principal.WindowsBuiltInRole.Administrator) End Function
/// <summary> /// 現在アプリケーションを実行しているユーザーに管理者権限があるか調べる /// </summary> /// <returns>管理者権限がある場合はtrue。</returns> public static bool IsAdministrator() { //現在のユーザーを表すWindowsIdentityオブジェクトを取得する System.Security.Principal.WindowsIdentity wi = System.Security.Principal.WindowsIdentity.GetCurrent(); //WindowsPrincipalオブジェクトを作成する System.Security.Principal.WindowsPrincipal wp = new System.Security.Principal.WindowsPrincipal(wi); //Administratorsグループに属しているか調べる return wp.IsInRole( System.Security.Principal.WindowsBuiltInRole.Administrator); }
上のコードではWindowsIdentity.GetCurrentメソッドを使用してWindowsPrincipalオブジェクトを作成していますが、Thread.CurrentPrincipalプロパティを使用する方法もあります。MSDNの「方法 : WindowsPrincipal プロジェクトを作成する」によると、WindowsIdentity.GetCurrentメソッドの方法は1回だけ検証を行なう場合に使用し、Thread.CurrentPrincipalプロパティを使った方法は繰り返して検証を行なう場合にオーバーヘッドが少なくて済むということです。
''' <summary> ''' 現在アプリケーションを実行しているユーザーに管理者権限があるか調べる ''' </summary> ''' <returns>管理者権限がある場合はtrue。</returns> Public Shared Function IsAdministrator2() As Boolean 'プリンシパルポリシーを設定する System.AppDomain.CurrentDomain.SetPrincipalPolicy( _ System.Security.Principal.PrincipalPolicy.WindowsPrincipal) 'WindowsPrincipalオブジェクトを作成する Dim wp As System.Security.Principal.WindowsPrincipal = _ DirectCast(System.Threading.Thread.CurrentPrincipal, _ System.Security.Principal.WindowsPrincipal) 'Administratorsグループに属しているか調べる Return wp.IsInRole( _ System.Security.Principal.WindowsBuiltInRole.Administrator) End Function
/// <summary> /// 現在アプリケーションを実行しているユーザーに管理者権限があるか調べる /// </summary> /// <returns>管理者権限がある場合はtrue。</returns> public static bool IsAdministrator2() { //プリンシパルポリシーを設定する System.AppDomain.CurrentDomain.SetPrincipalPolicy( System.Security.Principal.PrincipalPolicy.WindowsPrincipal); //WindowsPrincipalオブジェクトを作成する System.Security.Principal.WindowsPrincipal wp = (System.Security.Principal.WindowsPrincipal) System.Threading.Thread.CurrentPrincipal; //Administratorsグループに属しているか調べる return wp.IsInRole( System.Security.Principal.WindowsBuiltInRole.Administrator); }
上記のコードでは、UACが有効の時、ユーザーが管理者としてログオンしていたとしても、昇格していないのであれば、Falseが返されます。
UACが有効になっており、ユーザーが管理者に昇格しているか、いないかを調べるには、GetTokenInformation関数を使う方法があります。GetTokenInformationを使ってTOKEN_ELEVATION_TYPEを取得し、これがTokenElevationTypeFullであれば昇格しており、TokenElevationTypeLimitedであれば昇格していません。TokenElevationTypeDefaultであれば標準ユーザーか、UACが無効になっています。
以下にGetTokenInformationを使ってTOKEN_ELEVATION_TYPEを取得する例を示します。
'Imports System.Runtime.InteropServices <DllImport("advapi32.dll", SetLastError:=True)> _ Public Shared Function GetTokenInformation(ByVal TokenHandle As IntPtr, _ ByVal TokenInformationClass As TOKEN_INFORMATION_CLASS, _ ByVal TokenInformation As IntPtr, _ ByVal TokenInformationLength As UInteger, _ ByRef ReturnLength As UInteger) As Boolean End Function 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 End Enum Public Enum TOKEN_ELEVATION_TYPE TokenElevationTypeDefault = 1 TokenElevationTypeFull TokenElevationTypeLimited End Enum ''' <summary> ''' 昇格トークンの種類を取得する ''' </summary> ''' <returns>昇格トークンの種類を示すTOKEN_ELEVATION_TYPE。 ''' 取得に失敗した時でもTokenElevationTypeDefaultを返す。</returns> Public Shared Function GetTokenElevationType() As TOKEN_ELEVATION_TYPE Dim returnValue As TOKEN_ELEVATION_TYPE = _ TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault 'Windows Vista以上か確認 If Environment.OSVersion.Platform <> PlatformID.Win32NT OrElse _ Environment.OSVersion.Version.Major < 6 Then Return returnValue End If Dim tet As TOKEN_ELEVATION_TYPE = _ TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault Dim returnLength As UInteger = 0 Dim tetSize As UInteger = CUInt(Marshal.SizeOf(CInt(tet))) Dim tetPtr As IntPtr = Marshal.AllocHGlobal(CInt(tetSize)) Try 'アクセストークンに関する情報を取得 If GetTokenInformation( _ System.Security.Principal.WindowsIdentity.GetCurrent().Token, _ TOKEN_INFORMATION_CLASS.TokenElevationType, _ tetPtr, tetSize, returnLength) Then '結果を取得 returnValue = CType(Marshal.ReadInt32(tetPtr), TOKEN_ELEVATION_TYPE) End If Finally '解放する Marshal.FreeHGlobal(tetPtr) End Try Return returnValue End Function
//using System.Runtime.InteropServices; [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 } /// <summary> /// 昇格トークンの種類を取得する /// </summary> /// <returns>昇格トークンの種類を示すTOKEN_ELEVATION_TYPE。 /// 取得に失敗した時でもTokenElevationTypeDefaultを返す。</returns> public static TOKEN_ELEVATION_TYPE GetTokenElevationType() { TOKEN_ELEVATION_TYPE returnValue = TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault; //Windows Vista以上か確認 if (Environment.OSVersion.Platform != PlatformID.Win32NT || Environment.OSVersion.Version.Major < 6) { return returnValue; } TOKEN_ELEVATION_TYPE tet = TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault; uint returnLength = 0; uint tetSize = (uint)Marshal.SizeOf((int)tet); IntPtr tetPtr = Marshal.AllocHGlobal((int)tetSize); try { //アクセストークンに関する情報を取得 if (GetTokenInformation( System.Security.Principal.WindowsIdentity.GetCurrent().Token, TOKEN_INFORMATION_CLASS.TokenElevationType, tetPtr, tetSize, out returnLength)) { //結果を取得 returnValue = (TOKEN_ELEVATION_TYPE)Marshal.ReadInt32(tetPtr); } } finally { //解放する Marshal.FreeHGlobal(tetPtr); } return returnValue; }
このメソッドを使って昇格しているか調べる例を以下に示します。
Dim tet As TOKEN_ELEVATION_TYPE = GetTokenElevationType() If tet = TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault Then Console.WriteLine("UACが無効になっているか、標準ユーザーです") ElseIf tet = TOKEN_ELEVATION_TYPE.TokenElevationTypeFull Then Console.WriteLine("UACが有効になっており、昇格しています") ElseIf tet = TOKEN_ELEVATION_TYPE.TokenElevationTypeLimited Then Console.WriteLine("UACが有効になっており、昇格していません") End If
TOKEN_ELEVATION_TYPE tet = GetTokenElevationType(); if (tet == TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault) { Console.WriteLine("UACが無効になっているか、標準ユーザーです"); } else if (tet == TOKEN_ELEVATION_TYPE.TokenElevationTypeFull) { Console.WriteLine("UACが有効になっており、昇格しています"); } else if (tet == TOKEN_ELEVATION_TYPE.TokenElevationTypeLimited) { Console.WriteLine("UACが有効になっており、昇格していません"); }
.NET Framework 3.5からは、Principal.IsMemberOfメソッドによってユーザーが指定されたグループのメンバーであるか調べることができます。これを使って、現在のユーザーがローカル管理者グループのメンバーであるかを調べる例を示します。この方法であれば、昇格していなくても、管理者かどうかの確認ができます。なお、参照設定に「System.DirectoryServices.AccountManagement.dll」を追加することが必要です。
'Imports System.DirectoryServices.AccountManagement ''' <summary> ''' 現在のユーザーがローカルAdministratorsグループのメンバーか調べる ''' </summary> ''' <returns>メンバーであればtrue。</returns> Public Shared Function IsAdministratorsMember() As Boolean 'ローカルコンピュータストアのPrincipalContextオブジェクトを作成する Using pc As New PrincipalContext(ContextType.Machine) '現在のユーザーのプリンシパルを取得する Dim up As UserPrincipal = UserPrincipal.Current 'ローカルAdministratorsグループを探す '"S-1-5-32-544"はローカルAdministratorsグループを示すSID Dim gp As GroupPrincipal = GroupPrincipal.FindByIdentity(pc, "S-1-5-32-544") 'グループのメンバーであるか調べる Return up.IsMemberOf(gp) End Using End Function
//using System.DirectoryServices.AccountManagement; /// <summary> /// 現在のユーザーがローカルAdministratorsグループのメンバーか調べる /// </summary> /// <returns>メンバーであればtrue。</returns> public static bool IsAdministratorsMember() { //ローカルコンピュータストアのPrincipalContextオブジェクトを作成する using (PrincipalContext pc = new PrincipalContext(ContextType.Machine)) { //現在のユーザーのプリンシパルを取得する UserPrincipal up = UserPrincipal.Current; //ローカルAdministratorsグループを探す //"S-1-5-32-544"はローカルAdministratorsグループを示すSID GroupPrincipal gp = GroupPrincipal.FindByIdentity(pc, "S-1-5-32-544"); //グループのメンバーであるか調べる return up.IsMemberOf(gp); } }