85

昇格された特権で実行されているかどうかを検出する必要があるアプリケーションがあります。現在、次のようにコードを設定しています。

static bool IsAdministrator()
{
    WindowsIdentity identity = WindowsIdentity.GetCurrent();
    WindowsPrincipal principal = new WindowsPrincipal(identity);
    return principal.IsInRole (WindowsBuiltInRole.Administrator);
}

これは、ユーザーが管理者であるかどうかを検出するために機能しますが、昇格なしで管理者として実行している場合は機能しません。(たとえば、vshost.exe 内)。

昇格が[すでに実施されているか]可能かどうかをどのように判断できますか?

4

10 に答える 10

57

これを試してみてください:

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;
            }
        }
    }
}
于 2010-12-21T08:49:43.047 に答える
37

(質問されてから6年後の新しい回答)

免責事項: これは、特定のユーザーの特定の設定を使用して、特定の OS でたまたま機能したものです。

using System.Security.Principal;

// ...

    static bool IsElevated
    {
      get
      {
        return WindowsIdentity.GetCurrent().Owner
          .IsWellKnown(WellKnownSidType.BuiltinAdministratorsSid);
      }
    }

したがって、この「管理者として実行」を実行すると、プロパティgetアクセサーは を返しますtrue。正常に実行している場合 (ユーザーが「管理者」であっても、この特定のアプリケーションを「管理者として」実行していない場合でも)、 が返されますfalse

これは、他の多くの回答よりもはるかに簡単に思えます。

これが失敗する場合があるかどうかはわかりません。

PS!これも問題ないようです:

    static bool IsElevated
    {
      get
      {
        var id = WindowsIdentity.GetCurrent();
        return id.Owner != id.User;
      }
    }
于 2015-08-06T12:53:19.870 に答える
16

CodePlex プロジェクト UAChelperには、 UserAccountControl.cppの昇格をチェックするコードがUserAccountControl::IsUserAdminあり、UAC が有効になっているかどうかをチェックし、プロセスが昇格しているかどうかをチェックします。

bool UserAccountControl::IsCurrentProcessElevated::get()
{
    return GetProcessTokenElevationType() == TokenElevationTypeFull;    //elevated
}

関数から:

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);
    }
}
于 2009-08-03T00:05:30.867 に答える
11

.net Framwork 4.5 では、自分に合った別の方法を見つけました。ここで見つけることができる次のスクリプトに関連して(ドイツ語)

 rem --- Admintest.bat ---
 whoami /groups | find "S-1-5-32-544" > nul
 if errorlevel 1 goto ende
 echo Benutzer %username% ist lokaler Administrator.
 :ende

C# では次のようになります。

    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;
        }
    }

しかし、.net < 4.5 では、WindowsPrincipalクラスにUserClaimsプロパティが含まれておらず、この情報を取得する方法が見つかりませんでした。

于 2014-07-22T12:50:08.830 に答える
5

を使用しても機能しますが、管理者グループ SID に対してTokenElevationTypePInvokeを実行CheckTokenMembership()すると、コードは UAC がオフおよびオン 2000/XP/2003 のときにも機能し、拒否 SID も処理します。

IsUserAnAdmin()チェックを行う機能もありCheckTokenMembershipますが、MSDN によると、それは永遠に存在しない可能性があります

于 2009-08-04T22:40:02.240 に答える
2

もう1つ問題があると思います。あなたから提供された解決策を確認しましたが、Windows 7 のインストールで管理者としてログオンすると、チェックが機能しないと言わざるを得ません。Windows は、プロセスが昇格モードで実行されているという情報を返しません。したがって、シーケンス:

if (IsUacEnabled)
    return IsProcessInElevatedMode();
return IsUserAdmin();

管理者としてログインしている場合は true を返しませんが、プロセスにはシステム操作 (システム サービスの停止など) を実行するすべての権限があります。作業シーケンスは次のとおりです。

if (IsUserAdmin())
    return true;

if (IsUacEnabled)
    return IsProcessInElevatedMode();

return false;

まず、プロセスが管理者コンテキストで実行されているかどうかを確認する必要があります。追加情報:

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

その方法はすべて、以前の投稿で説明されています。

于 2015-01-14T15:08:30.677 に答える