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 に昇格しているか調べる方法を紹介してきました。
管理者権限が必要な処理を書くケースは少ないと思いますが、いざって時に使ってください。
0 件のコメント:
コメントを投稿