今まではXPが最終OSであったNaoten。
しかしリビングに設置したハードディスクレコーダーPCは
初めてWindows7を導入したPCとなりました。
使ってみて、便利になったと思う所もありますが、
不便になったと思う所もあります。
その最たる部分がUAC、つまり、
ユーザーアカウント制御機能です。
アプリケーションを起動すると出るこんな画面。
見たことないですかね??

んで、
UACを元からOFFれば、出ないのですけど、
これって不正なプログラムが
OSを書き換えるのを監視するシステムじゃないですか。
切るくらいならXP使えば?って思うわけです。
とは言え、特定のアプリケーションのみこのUACを切る事も出来ない。
どうしたもんか、と思って対策を考えてみました。
(以下、追記へ。)
ここから先の方法はWindows7上での説明になります。
他のOS上やログインユーザーが管理者で無い場合は
正常に動作しないので注意してください。
特定のプログラムのUAC回避に関しての手順は4つ。
1.プログラム実行スクリプトの作成
2.タスクスケジューラへの登録
3.プログラム個別のスクリプトの作成
4.実行
順に説明していきますが、
まず最初に、タスクスケジューラを介する理由を挙げておきます。
タスクスケジューラに登録されたプログラムは
実行する際に強烈な権限を持たせる事が出来ます。
この権限を使って実行すると、
UAC確認画面が表示されない、と言う仕組みを利用し、
UAC問題を回避しています。
1.プログラム実行スクリプトの作成
テキストエディタで新規ファイルを作ってもらって、
以下のソースを貼り付けるだけです。
(行番号は要りません。)
Option Explicit
Dim objWshShell ' WshShell オブジェクト
Dim objFS
Dim objFilePath
If WScript.Arguments.Count <> 0 Then
Set objWshShell = WScript.CreateObject("WScript.Shell")
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objFilePath = objFS.GetFile(WScript.Arguments(0))
objWshShell.CurrentDirectory = objFS.GetParentFolderName(objFilePath.ShortPath)
objWshShell.Exec(objFilePath.ShortPath)
End if
2012/03/20
コメント欄でのsootaさんのご提案とスクリプトのご提供を受け、
アプリケーション実行前のカレントディレクトリの移動と
ファイルパスをロングネームから8.3形式へ書き換える処理を追加しました。
ファイル名は何でもいいですが拡張子はvbsにしてください。
ここでは暫定的に「NaotenExec.vbs」と命名します。
保存をしてテキストエディタを閉じてください。
出来たファイルを置く場所もどこでもいいです。
好きな場所に設置して下さい。
2.タスクスケジューラへの登録
続いて、1.で作ったNaotenExec.vbsをタスクスケジューラに登録します。
スタートメニューをクリックして、
左下の「プログラムとファイルの検索」ボックスに
taskschd.msc /s
と入力し、エンターを押してください。
タスクスケジューラが起動します。
起動したらメニューの「操作」から「タスクの作成」を選んでください。
こんな画面が出るはずです。

名前の欄に「UACEscape」と入力してください。
それと必ず赤丸の部分。
「最上位の特権で実行する」にチェックを忘れないで下さい。
それ以外はデフォルトですが、
「場所」に関して「\」である事を確認しておいてください。
(\じゃない場合は覚えておいて下さい。)
続いて上のタブから「操作」を選び、
左下の「新規」ボタンを押してください。
こんな画面が出るはずです。

参照ボタンから先ほど配置したNaotenExec.vbsを選んでパスを設定してください。
また赤丸の部分に以下の様に入力してください。
$(Arg0)
OKボタンで新しい操作を登録後、
もう一度OKボタンを押して、タスクの登録も完了します。
これでタスクスケジューラの設定は終わりです。
3.プログラム個別のスクリプトの作成
最後は起動させたいプログラムを登録するスクリプトを作成します。
1.と2.は一度だけ行えば終わりですが、
この3.プログラム個別のスクリプトの作成は、
UACを回避したいプログラム毎に作る必要があります。
テキストエディタを起動し、新規ファイルを作成、
ファイル名は何でも構いませんが拡張子はvbsとしてください。
(ファイル名に関しては起動させたいプログラムに関連した名前が良いと思います。
例としてはメモ帳を起動するスクリプトの場合は「メモ帳.vbs」みたいに。
まぁ、メモ帳はUAC画面でないのでこれで起動する必要無いですけども。)
で、中身にはこれを書き写してください。(行番号は要りません。)
Option Explicit
Dim objTaskService
Dim objFolder
Dim objTask
Dim strAppPath
'' ===ここにプログラムのフルパスを設定===
strAppPath = "c:\???.exe"
'' タスクサービスオブジェクトの取得
Set objTaskService = CreateObject("Schedule.Service")
'' タスクサービスとの接続
objTaskService.Connect
'' 場所を指定してフォルダオブジェクトの取得
Set objFolder = objTaskService.GetFolder("\")
'' タスク名を指定してタスクオブジェクトを取得
Set objTask = objFolder.GetTask("UACEscape")
'' タスクを実行
objTask.Run """" & strAppPath & """"
上記の「ここにプログラムのフルパスを設定」
となっている下の行の"(ダブルコーテーション)に囲まれている部分、
「c:\???.exe」となっている所を起動したいプログラムのフルパスに書き換えてください。
先ほど2.の際に覚えておいた場所が「\」じゃ無かった場合、
上記プログラム中の
「場所を指定してフォルダオブジェクトの取得」
となっている下の行の"(ダブルコーテーション)に囲まれている部分、
「\」となっている所を覚えておいた場所に書き換えてください。
保存をしてテキストエディタを閉じてください。
4.実行
3.で作成したvbsファイルをダブルクリック。
お疲れさまでした。
UAC確認は回避されたと思います。
Naotenの場合、スタートアップで起動したいプログラムに
UAC確認画面が出てしまって困っていたので、
(自動で再起動とかした場合に、特定のプログラムが起動されない&煩わしい)
3.で作成したvbsファイルをスタートアップに登録し、
UACそのものを切ること無く問題を回避しました。
需要あるか解りませんけど、
ご参考になれば幸いです!
2012/03/20追記
この記事の内容でアプリケーションを起動した際に、
プロセスの優先度が低くて困る場合は記事中の
1.プログラム実行スクリプトの作成
で作成するvbsファイル(NaotenExec.vbs)を以下の様にして変更してみて下さい。
問題が解消される可能性があります。
ただしこれにより、
必ずプロセス優先度が意図したものになるとは限らない様です。
この記事はUAC回避が主題となりますので、
それらの問題に関しては別途、調査してみて下さいませ。
2012/08/15追記
maoyamaさんからのご要望にヒントを得て、
Drag&Dropに対応した子スクリプトを作りました。
テキストエディタで以下のソースを入力、
名前は記事上は暫定的にDragDrop.vbsとしデスクトップあたりに保存。
完成したこのDragDrop.vbsのアイコンの上にexeファイルやショートカットをドラッグすると、
そのプログラムが起動します。
スクリプトを起動したいプログラム分作るのは面倒な方は、こちらをお試しください(^^
2012/08/16追記
やはりエラー状況が解った方が対応しやすい、
と言う事で、sootaさんのご指摘に応じて
各スクリプト中から「On Error Resume Next」を削除しました。
2012/08/31追記
ItaRinさんのご要望を受けて、
NaotenExec.vbsにプログラムに引数を渡して起動する処理を追加しました。
上記に更新後は、
個別スクリプトのファイルパス設定の際にカンマ区切りで起動引数を設定出来ます。
またこのスクリプトに更新しても、起動引数が無くても従来通り起動します。
以下、メモ帳にパスを起動引数として渡し起動するサンプルです。
起動引数の数がいくつもあったとしても、カンマの数は1回にしてください。
例:
起動引数が無い場合
strAppPath = "%windir%\notepad.exe"
起動引数が1つの場合
strAppPath = "%windir%\notepad.exe,C:\test.txt"
起動引数が2つ以上の場合
strAppPath = "%windir%\notepad.exe,/A C:\test.txt"
起動引数に,(半角カンマ)を使用したい場合、
このままでは不適切なので、
NaotenExec.vbsと個別スクリプト内の区切り文字を別の文字に変更して下さい。
2014/12/09追記
benbenさんのご要望を受けて、
スタートアップ等で本スクリプトを複数同時起動する際の対応策を追記致します。
Option Explicit
Dim objTaskService
Dim objFolder
Dim objTask
Dim strAppPath
'' 指定ミリ秒待機
WScript.sleep(1000)
'' ===ここにプログラムのフルパスを設定===
strAppPath = "c:\???.exe"
(以下省略)
解説
スタートアップに複数の当スクリプトを登録した場合に1つしか起動しない問題は
まったく同時にタスクスケジューラにアプリケーションの起動要求をかけた事により
タスクスケジューラが2つ目以降の命令を無視する事により発生している可能性があります。
そこでタスクスケジューラに命令を与える時間をずらす事によりこの問題を回避します。
上記サンプル例では
'' 指定ミリ秒待機
WScript.sleep(1000)
と言う記述を追記しました。
これは指定したミリ秒だけそこでスクリプトを停止すると言う処理です。
サンプルでは1000ミリ秒を指定しておりこれは1秒だけ待機すると言う意味になります。
この処理をスタートアップに登録しているスクリプトの数に応じて、
少しずつずらして登録します。
1つ目のスクリプトではこの行が無い、もしくは0を指定して0秒待機としてください。
2つ目のスクリプトではこの値を1000、
3つ目のスクリプトではこの値を2000の様にします。
今回の例では間隔を1秒としましたが、
スペックの高いPCではこの間隔を狭めても問題ないと思いますし、
逆にスペックが低いPCではこの間隔を広げて試してみてください。
またダブルクリックした際も起動するまでその時間待機してしまうので、
スタートアップ登録版として別に生成するのが利便性上望ましいと思います。