[C#]アプリケーションのUAC対応

アプリケーション側で一般権限と管理者権限とで挙動を変えたい場合のメモ

  1. WindowsVista以降(UAC搭載OS)で起動されているか
    アプリケーションがWindowsVista以降で起動されているかどうかをOSのバージョン情報から判断する 

    using System;
    
    private bool IsUAC()
    {
        OperatingSystem osInfo = Environment.OSVersion;
        if (osInfo.Platform == PlatformID.Win32NT)
        {
            if (osInfo.Version.Major == 6)
            {
                if (osInfo.Version.Minor == 0)
                {
                    // Windows Vista, Windows Server 2008
                    return true;
                }
                else if (osInfo.Version.Minor == 1)
                {
                    // Windows 7, Windows Server 2008 R2
                    return true;
                }
            }
            else if (osInfo.Version.Major > 6)
            {
                // new Windows
                return true;
            }
        }
    
        return false;
    }
    
  2. アプリケーションが管理者権限で起動されているか
    アプリケーションが「管理者として実行…」されているとき 

    using System.Security.Principal;
    
    private bool IsAdministrator()
    {
        bool isAllowed = false;
    
        try
        {
            WindowsIdentity wi = WindowsIdentity.GetCurrent();
            WindowsPrincipal wp = new WindowsPrincipal(wi);
            isAllowed = wp.IsInRole(WindowsBuiltInRole.Administrator);
        }
        catch
        {
            isAllowed = false;
        }
    
        return isAllowed;
    }
    
  3. アプリケーションを起動したユーザーはAdministratorsグループに属しているか
    アプリケーションは一般権限で起動されていたとしても起動したユーザーが管理者に昇格可能かどうか知りたいとき 

    using System.DirectoryServices.AccountManagement;
    
    private bool IsAdministrators()
    {
        bool isAllowed = false;
    
        try
        {
            PrincipalContext pc = new PrincipalContext(ContextType.Machine, null);
            UserPrincipal up = UserPrincipal.Current;
            GroupPrincipal gp = GroupPrincipal.FindByIdentity(pc, "Administrators");
            if (up.IsMemberOf(gp))
            {
                isAllowed = true;
            }
        }
        catch
        {
            isAllowed = false;
        }
    
        return isAllowed;
    }
    

    上のコードだといくつかの環境でうまく動いていないっぽい?下のコードのほうが確実かも。

    using System.DirectoryServices.AccountManagement;
    
    private bool IsAdministrators()
    {
        bool isAllowed = false;
    
        try
        {
            PrincipalContext pc = new PrincipalContext(ContextType.Machine, null);
            UserPrincipal up = UserPrincipal.Current;
            foreach (GroupPrincipal gp in up.GetGroups())
            {
                try
                {
                    if (gp.Name.ToLower().Equals("Administrators".ToLower()))
                    {
                        isAllowed = true;
                    }
                }
                finally
                {
                    gp.Dispose();
                }
            } 
        }
        catch
        {
            isAllowed = false;
        }
    
        return isAllowed;
    }
    
  4. アプリケーションを管理者権限で再起動する
    処理を行う際に管理権限が必要となった場合に自分自身を管理者権限で再起動する 

    using System;
    using System.Diagnostics;
    
    private void RestartApplication()
    {
        ProcessStartInfo psi = new ProcessStartInfo();
        psi.UseShellExecute = true;
        psi.WorkingDirectory = Environment.CurrentDirectory;
        psi.FileName = Application.ExecutablePath;
        psi.Verb = "runas";
    
        try
        {
            Process p = Process.Start(psi);
        }
        catch
        {
            return;
        }
    
        Application.Exit();
    }
    
  5. 管理者権限が必要になるボタンにUAC(盾)のアイコンを表示する
    操作の続行に管理者権限が必要になることをユーザーに知らせるためボタンにUAC(盾)のアイコンを表示する
    (SystemIcons.Shieldプロパティの盾アイコンとWin32APIの盾アイコンには差があり、Windows 7で標準的に使われているのはWin32 APIのほうである。) 

    using System;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    
    namespace Sample
    {
        public partial class Form1 : Form
        {
            [DllImport("user32.dll")]
            private static extern IntPtr SendMessage(HandleRef hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
    
            // 第2パラメータ:盾アイコンを設定するフラグ
            uint BCM_SETSHIELD = 0x0000160C;
    
            public Form1()
            {
                InitializeComponent();
    
                // ボタンの外観を「System」にする必要がある
                button1.FlatStyle = FlatStyle.System;
            }
    
            private void checkBox1_CheckedChanged(object sender, EventArgs e)
            {
                // 第1パラメータ:ボタンのウィンドウ・ハンドル
                HandleRef hwnd = new HandleRef(button1, button1.Handle);
    
                if (checkBox1.Checked)
                {
                    SendMessage(hwnd, BCM_SETSHIELD, new IntPtr(0), new IntPtr(1));
                }
                else
                {
                    SendMessage(hwnd, BCM_SETSHIELD, new IntPtr(0), new IntPtr(0));
                }
            }
        }
    }
    

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です