NSISでインストーラ&アンインストーラを作っていて、インストール時に一緒にインストールしたAdobe AIRアプリケーションを、アンインストール時に同時にアンインストールしたいという要件。
Adobe AIRアプリケーションのアンインストールは、手動ならWindowsのコントロールパネルからできるので、ここの情報をレジストリから引っ張り出して実行すればOK。この辺は良くある手段。
で、レジストリからアンインストールに必要なプログラムの実行パス情報を持ってこようとしたら、Adobe AIRでは、Uninstall以下のサブキーの名前が毎回変わるので、検索する必要があることが発覚。
NSISにはレジストリの特定のキーを読む機能はあっても、キーを検索する機能はないので、DLLで拡張を作成。さっくり適当にC#でレジストリを検索して文字列を返すDLLを作成してみた。
ちなみにアンインストール情報はHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall以下にあります。
ということで、必要な動作はUninstall以下のサブキーを全部開いてDisplayNameが目的の名前と一致するサブキーを探すこと。ソースは以下。
SearchUninstall.cs
using System; using System.Collections.Generic; using System.Text; namespace SearchUninstall { public class SearchUninstall { public static string Find(string name) { string keyPath = ""; // レジストリからの読み取り Microsoft.Win32.RegistryKey regkey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", false); // キーが存在しないときは null が返される if (regkey == null) return null; // 文字列を読み込む // 読み込む値が存在しないときは null が返される string stringValue = (string)regkey.GetValue("string"); // sub以下のすべてのキー名を取得 string[] keyNames = regkey.GetSubKeyNames(); foreach (string k in keyNames) { string tmp_keyPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" + k; Microsoft.Win32.RegistryKey regkey2 = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(tmp_keyPath, false); try { string displayName = (string)regkey2.GetValue("DisplayName"); if (displayName == name) { keyPath = tmp_keyPath; break; } } catch (Exception e) { ; } finally { regkey2.Close(); } } //閉じる regkey.Close(); return keyPath; } } }
で、出来上がったDLLをNSISに読み込ませようとしても、どうにも動かない。
Dependency walkerで他のDLLと見比べてみると、C#で作られたDLLはエントリポイントが見えない。
そう言えばそんな話もあったような。
参考:WINAMP.COM | Forums – How can I use a C# DLL in NSIS
NSISからでは.NETのDLLが読めないらしい。ということで、見つけたのが以下。.NETのDLLを使えるようにするプラグイン。
Call .NET DLL methods plug-in – NSIS
CLR.zipをダウンロードしてきて、NSISをインストールしたフォルダのPluginsフォルダに入れておけばOK。
先に作ったSearchUninstall.dllはnsiファイルと同じ場所に入れておく。
で、nsiファイルは以下の感じ。Uninstall部分の必要部分を抜粋。
; アンインストーラ Section "Uninstall" ; アンインストールで使用するプラグインの準備 InitPluginsDir SetOutPath $PLUGINSDIR File "SearchUninstall.dll" ; AIRアプリケーションのアンインストーラを探す CLR::Call /NOUNLOAD "SearchUninstall.dll" "SearchUninstall.SearchUninstall" "Find" 1 "HogeHogeAir" pop $0 CLR::Destroy ReadRegStr $4 HKLM $0 "UninstallString" ; AIRアプリケーションのアンインストーラをPassiveモード(自動処理)で実行する ExecWait "$4 /passive" ; 後片付け Delete "$PLUGINSDIR\SearchUninstall.dll" SectionEnd
これで、アンインストール時にAdobe AIRアプリケーションのアンインストーラも勝手に起動して削除できる。
CLR超便利。プラグインを作るのが相当楽に。
[…] NSISで、C#で書かれた自作のDLLを使う : blog.loadlimit – digital matter – […]