管理者権限に昇格させるDLLの作り方

[戻る]
傾奇者 2017/01/12(木) 21:05:21
Visual Studio 2010、C++、MFC、SDI アプリです。
メニューの1つからレジストリをいじります。
このメニューを行う関数名を SetReg() とします。

管理者権限のない一般ユーザーは SetReg() を除くこのアプリ全体の機能を使えるように
し、管理者ユーザーはこのアプリを(管理者として起動ではなく)通常起動して使うが、SetReg() 
SetReg() を行うときだけ「ユーザーアカウント制御」ダイアログ(*)を出して管理者権
限でこのメニューを使う。
・・・というようにしたいです。
(*)『この不明な発行元からのアプリがデバイスに変更を加えることを許可しますか?』という
という奴です。

そこで、SetReg() だけを DLL として作成し、このアプリから呼び出すことにしました。
この DLL はこのアプリ専用なので、拡張 MFC DLL として作りました。
この DLL プロジェクトのプロパティで、リンカー→マニュフェストファイル→「UACの実
行レベル」を aslnvoker から requireAdministrator に変更しました。
次の2つはデフォルトのままです。
「ユーザーアカウント制御(UAC)を有効にする」・・・「はい」
「UACによるUI保護のバイパス」・・・「いいえ」

その結果ですが、このメニューを実行するとき「ユーザーアカウント制御」ダイアログが出
出ません。
管理者権限に昇格できず、関数は失敗し、レジストリがいじれません。

SetReg() を、DLL ではなく、別の実行型アプリ(SetReg.exe)として作成し、本体アプリ
から ShellExecute() で実行すれば「ユーザーアカウント制御」ダイアログが出て成功し
ますが、DLL では駄目でしょうか?
どうぞご教授をお願いいたします。

SetReg() の中身は、以下の通りです。

CRegKey reg;
if (reg.SetValue(HKEY_CLASSES_ROOT, _T(".abc"), _T("MyApp.abc")) != 
ERROR_SUCCESS) ::AfxMessageBox(_T("失敗"));
・・・(中略)
else if (reg.SetValue(HKEY_CLASSES_ROOT, _T("MyApp.abc\\shell\\open\\command"), 
_T("\"MyApp.exe\" \"%1\"")) != ERROR_SUCCESS) ::AfxMessageBox(_T("失敗"));

AR 2017/01/13(金) 11:06:26
 UACはシェル経由の実行で引っけてるようなので、DLL単体では制御不可だと思います。
 例えば、同じようなプロセスの実行でもCreateProcess()などのようにUACダイアログを
出せないものも存在してますからね。

傾奇者 2017/01/13(金) 15:26:26
[[解決]]
AR様 有難うございます。

DLLのプロジェクトで「UACの実行レベル」を requireAdministrator にしてコンパイルし
ても、デフォルトの aslnvoker のままでも、親アプリを管理者権限で起動しておけばDLLの
の関数は成功するので、requireAdministrator を使う場面は何だろうと、腑に落ちない
です。
ひょっとするとリンクの仕方次第で生きてくるのかも知れないと思います。
自分は難しいことが解らないので、簡単に def ファイルでやりました。

残念ですが、DLLに分離する方法は採用しないことにして、一応解決です。(^_^;)

古いスレッドには追加発言できません。