treedown’s Report

システム管理者に巻き起こる様々な事象を読者の貴方へ報告するブログです。会社でも家庭でも"システム"に携わるすべての方の共感を目指しています。

※https化しました。その影響でしばらくリンク切れなどがあるかもしれませんが徐々に修正していきます。 リンク切れなどのお気づきの点がございましたらコメントなどでご指摘いただけますと助かります。

アプリケーションをアンインストール後サイレントインストール

前回<Adobe AIRアプリのバージョンアップ時につまづいたこと - treedown’s Report>の改善版。
「バージョン確認でアンインストールを実行するとか、インストールバージョンの判定をするとか、もうちょっと判定処理を入れたくなってきた」をやってみることにしました。

前回の復習

前回<Adobe AIRアプリのバージョンアップ時につまづいたこと - treedown’s Report>のバッチファイルは単純に、
MsiExec.exe /uninstall {%アプリのGUID%} /quiet
でアンインストールを実行してから
"%実行パス%\arh.exe" -installAppSilent -desktopShortcut -programMenu "%インストーラ保存パス%\%AIRファイル名%.air"
でインストールを実行する、という処理を二行用意しただけのバッチでした。

これにバージョンを確認してアンインストールを実行する処理を加えてみました。

バージョンが複数ある?

調べてみたら、一つ前のバージョンだけでなく、いくつかの古いバージョンが存在することが分かりました。

前回はMsiExecで一つ前のバージョンのGUIDを指定してアンインストールを仕掛けていましたが、これだけでは不足することになります。

今回は二つ前の古いバージョンまでのアンインストールを実施してからインストールを実行するように判定とアンインストール処理を作ってみることにします。

UninstallStringを確認

各バージョンでレジストリエディタを確認してみました。

アプリケーションのUninstallStringが記録されている箇所は、

HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall

配下のアプリ名のキーで固定されています。このキーの中に

画像はイメージです。実際の画面ではありません。

UninstallStringの記述を確認しました。今回対象としたどちらのバージョンでも同じキー名の中に異なるUninstallStringが記載されています。
また、同じキーの中に「DisplayVersion」の値があり、バージョンの数字がここで保持されていることも確認できたので、これでバージョンの判定がある程度できそうです。

さっそくバッチ作成に取りかかりました。

バッチファイル

バッチファイルは簡単に、「アンインストール対象のバージョンが存在するかどうか」を判定し、存在すればアンインストールを実行⇒新しいバージョンをインストール、という処理を行っています。
ただ、対象バージョンが二つあるので、一つ目のバージョン判定が「存在なし」となった場合には、もう一つのバージョン判定に移動するようにIF文を用意しました。

当然ですが、インストールに管理者権限が必要な場合には権限代行ソリューションなどでバッチファイルの実行時にインストール権限を付与する必要があります。

-------------------------------------------------------------------------------------------------
@echo off

reg query "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\%AppNAME%" | findstr "4.5"
    if %ERRORLEVEL% == 0 goto NXv45exec
    if %ERRORLEVEL% == 1 goto NoExistv45

:NXv45exec
rem echo Version4.5を発見しました。アンインストールします。
msiexec /qb /x {%アプリのGUID%}
rem echo 実際にはコメント行を外して処理を実行します。
goto InstNewer

:NoExistv45
rem 次のバージョン判定
reg query "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\%AppNAME%" | findstr "5.0"
    if %ERRORLEVEL% == 0 goto NXv50exec
    if %ERRORLEVEL% == 1 goto NoExistv50

:NXv50exec
rem echo Version5.0を発見しました。アンインストールします。
MsiExec.exe /uninstall {%アプリのGUID%} /quiet
rem echo 実際にはコメント行を外して処理を実行します。
goto InstNewer

:NoExistv50
reg query "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\%AppNAME%" | findstr "5.1"
    if %ERRORLEVEL% == 0 goto NXv51exec
    if %ERRORLEVEL% == 1 goto NoExistv51

:NXv51exec
rem echo 既に最新版がインストールされています。⇒何もせず終了
goto end

:NoExistv51
rem echo どれにも当てはまりませんので何もせず終了します。
goto end

:InstNewer
rem サイレントインストール(自動実行用)
"c:\temp\installdir\arh.exe" -installAppSilent -desktopShortcut -programMenu "c:\temp\installdir\InstApp.air"

:end
rem 終了
-------------------------------------------------------------------------------------------------

サイレントインストール用なのでecho行は全てremを付けてコメントアウトしていますが、実際に動作確認する際にはコメント行を有効にした方が分かりやすいです。

コマンドreg queryでどのバージョンがインストールされているかを探し出して、合致したバージョンに対応するUninstallStringを実行してアプリケーションを削除、削除後には新バージョンのインストールを実行するコマンドラインにジャンプして新バージョンのインストールを行います。

判定は二つ前の旧バージョンまでを判定するので、reg queryとIF文で判定する処理は(インストールする新バージョンも合わせて)三セット用意しています。

なんか、もうちょっと変数を使って見やすいバッチファイルにしたいかなぁと思ったのですが、一時的にしか使わないバッチファイルということもあってそんなに時間を掛ける処理でもなく、ひとまずこれで公開としました。