アプリケーションを管理者権限で起動するにはコンテキストメニューから「管理者として実行」を行う必要があります。
しかし、起動時に毎回「管理者として実行」をするにはいささか面倒です。そこで、プログラムを実行したときに自動的に自分自身で管理者権限に昇格する方法を記載します。
マニフェストファイルに定義する方法が一般的のようですがコンソールアプリで簡単に記述できたら便利なので今回のような方法を採用しています。
開発環境
管理者権限の確認と昇格方法
自分自身で管理者権限に昇格するのは難しいので、管理者権限で起動されていなかったら、管理者権限をつけた別プロセスを起動し、自分は終了します。
今回は、コンソールアプリで作成しています。コンソールウィンドウを隠して2重起動防止をしています。
using System;
using System.Diagnostics;
using System.Reflection;
using System.Security.Principal;
using System.Threading;
static void Main(string[] args)
{
// 管理者権限を付けて別プロセスで起動する。自分は終了する
// しかし、UACのダイアログは表示される
Thread.GetDomain().SetPrincipalPolicy(System.Security.Principal.PrincipalPolicy.WindowsPrincipal);
var pri = (WindowsPrincipal)Thread.CurrentPrincipal;
if (!pri.IsInRole(WindowsBuiltInRole.Administrator)) // 管理者権限ではないとき
{
var proc = new ProcessStartInfo()
{
WorkingDirectory = Environment.CurrentDirectory,
FileName = Assembly.GetEntryAssembly().Location,
Verb = "RunAs" // 管理者権限を付与
};
proc.Arguments = string.Join(" ", args);
Process.Start(proc); // 別プロセスで自分を再度起動する
return; // 自分終了
}
var p = Process.GetCurrentProcess();
// int SW_HIDE = 0;
// ShowWindow(p.MainWindowHandle, 0); // HideにするとタスクマネージャApplicationsに表示されない
SetWindowPos(p.MainWindowHandle, new IntPtr(1), 0, 0, 0, 0, 0x13); // ウィンドウを隠す。タスクバー表示。タスクマネージャに表示
// 2重起動防止
String mutexName = "MameMame";
// Mutexオブジェクトを作成する
bool createdNew;
System.Threading.Mutex mutex = new System.Threading.Mutex(true, mutexName, out createdNew);
if(createdNew == false)
{
mutex.Close();
return;
}
try
{
// ここにアプリケーション実行処理を記述する
}
finally
{
// ミューテックス解放
mutex.ReleaseMutex();
mutex.Close();
}
}
「ユーザーアカウント制御」が有効になっている場合は、起動時に「アプリがデバイスに変更・・・」のダイアログが表示されますが、これはしょうがないでしょうか。
いままでは「ユーザーアカウント制御(UAC)」を無効にして利用していましたが、Windows11にしてからはデフォルトのまま利用しています。
こまごまとしたアプリケーションを作成し、他の人に利用していただいていると、やはりデフォルトの設定で利用されている方に合わせないといけないな、と感じることが多くなってきましたので。