PLAN_VBA_API_REGISTRY_UAC 本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
Win32 APIでセキュアに取得するUAC(ユーザーアカウント制御)設定状態の確認手法
【背景と目的】
VBAによるファイル操作やシステム連携時、UAC(ユーザーアカウント制御)の制限による書き込みエラーが頻発します。事前にレジストリからUACの状態を判定し、適切な警告を出すことで実行時エラーを未然に防ぎます。
【処理フロー図】
graph TD
A["開始"] --> B["Win32 APIでレジストリキーを開く"]
B --> C{"キーの展開に成功?"}
C -->|Yes| D["EnableLUAの値を読み取り"]
C -->|No| E["エラー処理: 権限不足等"]
D --> F{"値が 1 か?"}
F -->|Yes| G["UAC 有効と判定"]
F -->|No| H["UAC 無効と判定"]
G --> I["レジストリハンドルを閉じて終了"]
H --> I
E --> I
【実装:VBAコード】
Option Explicit
' --- Win32 API 宣言 (64bit/32bit 両対応) ---
Private Declare PtrSafe Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" ( _
ByVal hKey As LongPtr, _
ByVal lpSubKey As String, _
ByVal ulOptions As Long, _
ByVal samDesired As Long, _
ByRef phkResult As LongPtr) As Long
Private Declare PtrSafe Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" ( _
ByVal hKey As LongPtr, _
ByVal lpValueName As String, _
ByVal lpReserved As Long, _
ByRef lpType As Long, _
ByRef lpData As Any, _
ByRef lpcbData As Long) As Long
Private Declare PtrSafe Function RegCloseKey Lib "advapi32.dll" ( _
ByVal hKey As LongPtr) As Long
' --- 定数定義 ---
Private Const HKEY_LOCAL_MACHINE As LongPtr = &H80000002
Private Const KEY_QUERY_VALUE As Long = &H1
Private Const ERROR_SUCCESS As Long = 0&
Private Const REG_DWORD As Long = 4
''' <summary>
''' UAC (EnableLUA) の状態を確認するメイン関数
''' </summary>
''' <returns>True: 有効, False: 無効または取得失敗</returns>
Public Function IsUACEnabled() As Boolean
Dim hKey As LongPtr
Dim subKey As String
Dim valueName As String
Dim dwValue As Long
Dim cbData As Long
Dim lngRet As Long
' 高速化設定(本処理はUI非依存だが、慣例として定義)
Application.ScreenUpdating = False
' UAC設定が格納されているレジストリパス
subKey = "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
valueName = "EnableLUA"
cbData = 4 ' DWORDのサイズ
' 1. レジストリキーを開く
lngRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, subKey, 0, KEY_QUERY_VALUE, hKey)
If lngRet = ERROR_SUCCESS Then
' 2. 値を取得
lngRet = RegQueryValueEx(hKey, valueName, 0, REG_DWORD, dwValue, cbData)
' 3. ハンドルを閉じる
RegCloseKey hKey
If lngRet = ERROR_SUCCESS Then
' EnableLUA = 1 ならば UAC 有効
IsUACEnabled = (dwValue = 1)
End If
Else
' キーが開けない場合は権限不足またはパス不在
IsUACEnabled = False
End If
Application.ScreenUpdating = True
End Function
''' <summary>
''' 動作確認用プロシージャ
''' </summary>
Sub CheckUACStatus()
If IsUACEnabled() Then
MsgBox "UAC(ユーザーアカウント制御)は【有効】です。" & vbCrLf & _
"管理者権限が必要な操作でエラーが出る可能性があります。", vbInformation
Else
MsgBox "UAC(ユーザーアカウント制御)は【無効】です。", vbExclamation
End If
End Sub
【技術解説】
Win32 APIの使用: 標準の
WScript.Shell(RegRead) でも取得可能ですが、Win32 API を使用することで、参照設定を不要にしつつ、動作速度の向上とエラーハンドリングの厳密化(戻り値による判定)を実現しています。PtrSafe と LongPtr: 64bit版のExcelでも安全に動作するよう、ポインタ(ハンドル)を扱う変数には
LongPtrを使用し、宣言にはPtrSafeを付与しています。レジストリパス: UACの核となる
EnableLUA値をHKEY_LOCAL_MACHINEから参照しています。ここはOS全体のセキュリティ設定を司る場所です。
【注意点と運用】
読み取り権限: 通常、このレジストリキーの読み取りには管理者権限は不要(一般ユーザーでOK)ですが、環境によってはセキュリティソフトがAPIによるレジストリアクセスをブロックする可能性があります。
レジストリ操作のリスク: 本コードは「読み取り」のみを行いますが、誤って
RegSetValue等を実行しないよう注意してください。反映タイミング: UACの設定を変更した場合、OSを再起動するまでレジストリ上の値と実際の動作が乖離するケースがあります。
【まとめ】
Win32 API(advapi32.dll)を活用し、高速かつ参照設定不要で情報を取得。
EnableLUAの値を参照することで、プログラムの動作環境を事前に把握。エラーハンドリングをAPIの戻り値
ERROR_SUCCESSで判定し、堅牢なツール設計に。

