C#で UAC に昇格しているか調べる方法

2023年1月13日金曜日

C#

t f B! P L

enter image description here

Windowsアプリケーション開発で、例えば System32 などに対する操作をする場合など、管理者権限が必要な処理を行う場合、UAC の昇格を行う必要がある。

この記事では .NETアプリ(C#)で、自分のプロセスが UAC の昇格を行っているか判定する方法について紹介する。

はじめに

サンプルコードは、以下の .NET バージョンで確認していますが、ほかのバージョンでも基本は同じです。

.NET Framework 4.8

STEP1)OSバージョンの確認

今さら Windows XPなどの古い OS の考慮は不要かと思いますが、UAC は Windows Vista 以降で導入された機能のため、OS バージョンが Windows Vista 以降であるか確認します。

また、.NET Core や .NET 5 以降のバージョンについては、macOS や Linux で動作するため、Windows 以外の OS 以外の場合は、UAC の判定は行わないように制御します。

具体的なサンプルコードは、以下のようになります。

if (Environment.OSVersion.Platform != PlatformID.Win32NT ||
Environment.OSVersion.Version.Major < 6)
{
    Console.Write("対象外の OS・バージョンです");
    return;
}

UAC の昇格判定

前の手順で、UAC 昇格対象のOSバージョンとなった場合に、自分のプロセスが UAC の昇格がされているか判定します。

Win32 APIの定義

UAC の昇格判定は、GetTokenInformation Win32 API 関数を使うため、以下の extern 関数と引数の指定で使う enum を定義しておきます。

[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool GetTokenInformation(
    IntPtr TokenHandle,
    TOKEN_INFORMATION_CLASS TokenInformationClass,
    IntPtr TokenInformation,
    uint TokenInformationLength,
    out uint ReturnLength);

//GetTokenInformationで取得する値の種類を表す列挙型
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,  //UACが無効になっているか標準ユーザ
    TokenElevationTypeFull,         //管理者に昇格している
    TokenElevationTypeLimited       //管理者に昇格していない
}

昇格レベルの取得

上で定義した GetTokenInformation Win32 APIを呼び出し、トークンの昇格レベルを取得する。

//戻り値 TokenInformation のサイズ測定とメモリ確保
TOKEN_ELEVATION_TYPE returnValue = TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault;
uint tokenInformationLength = (uint)Marshal.SizeOf((int)returnValue);
IntPtr tokenInformation = Marshal.AllocHGlobal((int)tokenInformationLength);
   
try
{
    //アクセストークンに関する情報を取得
    uint returnLength;
    if (GetTokenInformation(
            System.Security.Principal.WindowsIdentity.GetCurrent().Token,
            TOKEN_INFORMATION_CLASS.TokenElevationType,
            tokenInformation, tokenInformationLength, out returnLength))
    {
        //結果を取得
        returnValue = (TOKEN_ELEVATION_TYPE)Marshal.ReadInt32(tokenInformation);
        switch (returnValue) {
            case TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault:
                Console.Write("UACが無効か、標準ユーザーです");
                break;
            case TOKEN_ELEVATION_TYPE.TokenElevationTypeFull:
                Console.Write("管理者に昇格しています!!");
                break;
            case TOKEN_ELEVATION_TYPE.TokenElevationTypeLimited:
                Console.Write("管理者に昇格していません(涙)");
                break;
        }
    }
}
finally
{
    //メモリを解放する
    Marshal.FreeHGlobal(tokenInformation);
}

まとめ

C#で UAC に昇格しているか調べる方法を紹介してきました。
管理者権限が必要な処理を書くケースは少ないと思いますが、いざって時に使ってください。

スポンサーリンク
スポンサーリンク

このブログを検索

Profile

自分の写真
Webアプリエンジニア。 日々新しい技術を追い求めてブログでアウトプットしています。
プロフィール画像は、猫村ゆゆこ様に書いてもらいました。

仕事募集もしていたり、していなかったり。

QooQ