前回投稿した下記記事の「さらなる問題」において、プロパティARPNOREMOVEPP
を設定することにより「アプリと機能」や「プログラムと機能」で「アンインストール」を無効にした場合、WixUIの標準ダイアログである「メンテナンス種別選択画面」(正式名称ではないが便宜上そう呼ぶことにする)でも「削除」ボタンが使用不可となる問題が発生していた。
結論から言うと、この問題は「メンテナンス種別選択画面」でも、ARPNOREMOVEPP
の値により「削除」ボタンの使用可否の切り替えが行われていることに起因している。
この記事では問題解決のために、「メンテナンス種別選択画面」の動作をカスタマイズする方法について説明する。
WiX Toolset のソースコードをダウンロードする
「メンテナンス種別選択画面」の仕様を把握するために、まず Github より WiX Toolset のソースコード一式をダウンロードする。
現時点(2022/07/04) の最新版である、Ver.3.11.2 のソースコードは上記URLからダウンロードできる。「Assets」のうち、「Source code (zip)」でも「Source code (tar.gz)」でも、好きなアーカイブ形式を選んでダンロードすればよい。
アーカイブを展開したディレクトリツリーのうち、「src\ext\UIExtension\wixlib」には、WixUIの標準ダイアログの内容や画面遷移が定義された *.wxs ファイル、およびダイアログで使用されるメッセージが言語別に定義された *.wxl ファイルが多数格納されている。
「メンテナンス種別選択画面」のソースコード
上述のディレクトリに格納された、 *.wxs ファイルのうち、 MaintenanceTypeDlg.wxs に「メンテナンス種別選択画面」が定義されているので、その内容を確認してみる。
下記のコードは、 MaintenanceTypeDlg.wxs から「削除」ボタン(RemoveButton
)およびその説明テキスト(RemoveText
、RemoveDisabledText
)に該当する部分を抜粋したものである。
<Control Id="RemoveButton" Type="PushButton" X="40" Y="171" Width="80" Height="17" ToolTip="!(loc.MaintenanceTypeDlgRemoveButtonTooltip)" Text="!(loc.MaintenanceTypeDlgRemoveButton)">
<Publish Property="WixUI_InstallMode" Value="Remove">1</Publish>
<Condition Action="disable">ARPNOREMOVE</Condition>
</Control>
<Control Id="RemoveText" Type="Text" X="60" Y="191" Width="280" Height="20" NoPrefix="yes" Text="!(loc.MaintenanceTypeDlgRemoveText)">
<Condition Action="hide">ARPNOREMOVE</Condition>
</Control>
<Control Id="RemoveDisabledText" Type="Text" X="60" Y="191" Width="280" Height="20" NoPrefix="yes" Text="!(loc.MaintenanceTypeDlgRemoveDisabledText)" Hidden="yes">
<Condition Action="show">ARPNOREMOVE</Condition>
</Control>
「削除」ボタンやその説明テキストは<Condition Action="disable">ARPNOREMOVE</Condition>
のようにARPNOREMOVE
プロパティによって、使用可否や表示/非表示が制御されており、このプロパティの値が設定されていない状態にすれば、「削除」ボタンを使用可能にできることが分かる。
「削除」ボタンを使用可能にする
特定のタイミングおよび条件でARPNOREMOVE
プロパティを変更するには、下記のようなカスタムアクションを実行すればよい。
<CustomAction
Id="TurnNoRemoveOff"
Property="ARPNOREMOVE"
Value=""
/>
このカスタムアクションを「メンテナンス種別選択画面」が表示される時に実行すればよいわけだが、具体的にどのように設定すれば実現可能なのか? それを探るために、ビルドされたMSIファイルをorcaで覗いてみる。
このスクリーンショットでは、oraca でInstallUISequence
テーブルの内容が表示されている。
複数定義されたAction
のうちMaintenanceWelcomDlg
は「メンテナンス種別選択画面」の前に表示されるウェルカム画面であり、この画面が表示される時に同じ条件で、上述のカスタムアクションTurnNoRemoveOff
を実行すれば、その次に表示される「メンテナンス種別選択画面」でもARPNOREMOVE
プロパティに値が設定されていない状態にすることができる。
MaintenanceWelcomDlg
が表示される条件はCondition
列を見るとInstalled AND NOT RESUME AND NOT Preselected AND NOT PATCH
となっているので、これらの情報を踏まえてInstallUISequence
を下記のように設定する。
<InstallUISequence>
<Custom Action="TurnNoRemoveOff" Before="MaintenanceWelcomeDlg">
Installed AND NOT RESUME AND NOT Preselected AND NOT PATCH
</Custom>
</InstallUISequence>
カスタマイズ結果
前節のとおり、カスタムアクションによりARPNOREMOVEPP
プロパティの値を変更するようにしたインストーラを用いてアプリをインストールし、「アプリと機能」より「変更」を選択すると、「メンテナンス種別選択画面」は下記のようになる。
「削除」ボタンを使用可能とすることができた。