読者です 読者をやめる 読者になる 読者になる

UACの権限昇格ダイアログ

Webアプリケーションの開発を行っているとあまり意識しないのですが、既存のスタンドアロンJavaプログラムをWindows 7にて動作検証する必要があり、ユーザアカウント制御(UAC)について調査しました。普段はWindows XPを使用しているのでUACに馴染みがなく、UAC自体を理解するのに少し手間取りました。。

UAC

XPまでは実行するアカウントに管理者権限があれば、レジストリやシステムフォルダなどへの変更も自由に行うことができましたが、UACが有効になったVista/7ではアプリケーションの実行時に管理者権限を取得する必要があります。ここでアプリケーションをインストールしたProgram Files内もシステムフォルダに該当します。ですので、ユーザ権限では、インストールフォルダに設定ファイルを作成したり、ログを出力したりすることはできませんでした(javaでは「アクセスが拒否されました」というエラー)。この場合、次のような対応を行う必要があります。

  1. 設定ファイルやログをユーザーフォルダに作成するようにする
  2. java.exeを実行するコマンドプロンプト、バッチファイルや管理者権限で実行する

権限昇格ダイアログ

今回の検証対象は、java.exeを実行するのではなくNSISで作ったランチャー(exeファイル)を経由して起動されます。NSISはオープンソースのインストーラ作成ソフトですが、外部プログラムを実行できるので内部でjavaw.exeを実行するランチャーとして使っています。

このプログラムをWindows7にインストールしたところ、アイコンに管理者権限が必要な印である盾マークが表示されました。

実行すると次のような権限の昇格確認のダイアログが表示されます。

プログラムが必要とする権限はプログラム自体に記述することができ、記述がない場合にはWindowsが判断しているようです。

NSISでの権限の指定はインストーラスクリプトのRequestExecutionLevelというコマンドで指定します。

RequestExecutionLevel admin

Scripting Reference
システムフォルダへのアクセスが不要であれば"user"を指定すれば、ダイアログは回避できます。

しかし、システムフォルダへのアクセスが必要な場合、プログラムを起動するたびにこのダイアログが表示されるのは少しウザイです。最初はプログラムの作り方次第で回避できるのでは?と考えたのですがUACの存在意義を考えるとそんなことはできないですよね。。

すべてのプログラムでダイアログを表示せずに昇格させることは可能です。管理ツールのローカルセキュリティポリシーを起動し、

[ローカルポリシー] - [セキュリティオプション] から "ユーザーアカウント制御: 管理者承認モードでの管理者に対する昇格時のプロンプトの動作"にて、"確認を要求しないで昇格する"を選択します。

ただし、この設定ではすべてのプログラムが確認なしに昇格可能でセキュリティ上問題があるように思います。

とりあえずは、1日に何度も起動する種類のプログラムでもないので、毎回ダイアログを表示することでも問題はないだろうという結論にいたりました。

タスクスケジューラからの実行

検証対象のプログラムは、タスクスケジューラからも実行する必要のあるプログラムだったのですが、登録したタスクのプロパティにて、"最高位の特権で実行する"にチェックをつければOKでした。

参考

とりとめなく書いてしまいましたが、↓のサイトにまとまっていました。
4 Ways to Make UAC Less Annoying on Windows 7 / Vista - How-To Geek

UACのウザさを軽減する方法として、次の4つがあげられています。

  1. UACを無効にする
  2. ダイアログを表示せずに昇格させる
  3. ブラックアウトさせない
  4. ダイアログを表示せずに管理者権限で起動するショートカットを作成する

4番目の方法は、プログラムをタスクスケジューラ経由で起動することで、権限昇格ダイアログを回避するというものです。具体的な手順は次の通りです。

  1. 実行したいプログラムをタスクスケジューラに登録("最高位の特権で実行する")
  2. タスクを起動するショートカット(schtasks /run /tn "タスク名")を作成する
  3. ショートカットのアイコン等を変更する