ネタ元:恐怖のアンインストール
その昔 GDNJ でも VS2003 で同じネタがあったのですが(おれがコメントつけてやんのww)、VS2005 にも同じバグが残されたままでした。
細かい状況は、ネタ元を見てもらうとして...w
レジストリキーのプロパティをみると、
| 名称 | 型 | 属性 |
| (Name) | 文字列 | |
| AlwaysCreate | Bool | |
| Condition | 文字列 | |
| DeleteAtUninstall | Bool | |
| FullPath | 文字列 | 読み取り専用 |
| Transitive | Bool | |
というプロパティが並んでいます。
ここで、バグの遠因になっているであろう問題が一つ。Registry Table には Condition がありません(Transitiveは、Conditionの再評価なので、これも付いていないことになります)。
ではこれはどこについているか?というと、そのレジストリを持つコンポーネントが持っています。
ORCAを持ってる人は、適当にこさえたmsiでRegistry Tableを参照し、そこの Component_ にある値で検索してみるとよいでしょう。
Component Table にConditionが書かれています(TransitiveをTrueにすると、Attributesの値が変わります)。
VSセットアップでは、1エントリー1コンポーネントという贅沢な造りをしているので(原則)、機能上はこれでも全く問題ありません。トランスレータが正しければ...ですがw
実際はどうか?というと、msi に落とし込む(変換する)際、どうも間違った解釈をするらしく、Conditionにデータがあると、DeleteAtUninstall プロパティが True であると解釈されているようです(重要:AlwaysCreate=Falseの場合のみ)。
まず、この動作の前に、それぞれのフラグの説明をしておきましょう。
上記プロパティのうち、Registry Table に直接影響を与えるものは、(Name)、AlwaysCreate、DeleteAtUninstall の3つのプロパティだけ(のはず)です。
このうち、Nameは、キー名ですので、これについては改めて意識する必要はないと言えるでしょう。
問題は、残りの二つ。
これら二つは排他制御ではなく、ビット合成にあたるプロパティです(それぞれ、別々に設定したもので4通りを表現する)。
組み合わせは、False+False, True+False, False+True, True+True の4つです。
これらは、msi 上では、"", "+", "-", "*" の4つにマッピングされます。
まず、両方が False の ""。こちらは、デフォルトの動作でもあり、キーがなければインストール時に作成し、アンインストール時に消してもよければ消す(消してもよい=値やサブキーがない)という動作になります。
次が、AlwaysCreateのみTrueの"+"。こちらは、サブキーなどを持っていない空のキーでもインストール時に作成という動作になります。
DeleteAtUninstall のみ True の "-" は、ある意味危険なプロパティですが、アンインストール時に該当キーを「状況にかかわらず」削除するかどうかを指定します。
さいごが両方Trueの"*"。こちらは文字通りAlwaysCreate とDeleteAtUninstall の両方の動作をするものです。
さて、VSセットアップがmsiに落とし込んでいる際に、これらがどう解釈されているのかですが、実際に組み合わせて作ってみました。
組み合わせ表現は、AがAlwaysCreate、C がCondition、D が DeleteAtUninstall でFはFalse, TはTrueです。
それぞれの結果と、個人的な予測の表を作ってみました。
| 組み合わせ | 結果 | 予測 |
| AF_CF_DF | 存在しない | ""で存在 |
| AF_CF_DT | - | - |
| AF_CT_DF | - | ""で存在 |
| AF_CT_DT | - | - |
| AT_CF_DF | + | + |
| AT_CF_DT | * | * |
| AT_CT_DF | + | + |
| AT_CT_DT | * | * |
となりました。
予測と異なっていたのは2か所。というか、表の一番上は今回全パターンを組み合わせて初めて分かった...w
ま、とりあえず MSDN フォーラム 行きですなw