3

編集:以下のコメントの1つで問題をよりよく要約したので、自分自身を引用します…</ p>

パッケージがインストールされているときは真であるが、削除されているときは真ではないという条件があります。MSIは、条件付きコンポーネントをインストールし、アンインストールで削除したことを覚えていると思っていましたが、そうではありません。私は、A)この孤立したコンポーネントをクリーンアップする適切な方法、およびB)将来この問題から保護するための最良の方法を見つけようとしています。

私の質問は要約すると、製品がアンインストールされた後に孤立した機能/コンポーネントを削除するだけで安全ですか?そして、もしあれば、私が孤立していると信じているコンポーネントをまだ参照しているものをチェックする方法はありますか?そして、将来これが起こらないようにインストーラーを修正するにはどうすればよいですか?

ライブラリFooをインストールするためのwixプロジェクトがあります。このインストーラーは、デフォルトでFoo.dllのコピーをGACとフォルダーに配置Program Files\Reference Assemblies\Foo\<version>します。インストーラーは2つのレジストリキーも追加します。1つは将来のインストールで再利用するためにFooフォルダーのパスを格納するカスタムキーで、もう1つはインストール<version>されたライブラリの検索に完全なフォルダーパスを含めるようにVisual Studioに指示し、Fooがに表示されるようにします。 「参照の追加」ダイアログ。Fooライブラリの複数のバージョンを一度にマシンにインストールできます。各バージョンはFooの<version>下の適切なフォルダにあります。

Foo 2.0.0にはテストをすり抜けたバグがあり、Foo 2.0.1にはバグ修正が含まれており、他の変更はありませんでした。バグ修正が唯一の変更であったため、GACにポリシーファイルを追加して、Foo2.0.0の参照をFoo2.0.1にリダイレクトすることが決定されました。このポリシーファイルは、新機能内の新しいコンポーネントとしてインストーラーに追加されました。Foo2.0.1がインストールされたときにFoo2.0.0を検出して削除するために、アップグレードタグが追加されました。ポリシー機能のインストールは、Foo2.0.0が検出されることを条件として行われました。すべてが機能しているようで、Foo2.0.1がプッシュされました。

1年後、今度はライブラリコードではなく、インストーラーのセットアップでバグに気付かなかったことがわかりました。Foo 2.0.1が2.0.0を置き換えてからアンインストールすると、ポリシーファイルは孤立し、GACに残りますが、他のすべてのファイルとキーは削除されます。私はこれをWindowsのクリーンインストールでテストし(仮想マシンは非常に便利な場合があります)、問題を再現できることを確認しました。つまり、コンポーネントへの追加の参照が侵入して、コンポーネントが遅れないことを確認しました。

これはすべて元々WiX3.0で行われていましたが、最近WiX3.5の使用に移行しました。WiXコードは次のようになります。

<Product Id="Guid 1" Name="Foo v2.0.1" Language="1033" Version="2.0.1" Manufacturer="My Team" UpgradeCode="Guid 2">

  <Package InstallerVersion="300" Compressed="yes" />

  <Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />

  <Upgrade Id="Guid 2">
    <UpgradeVersion Minimum="2.0.0" Maximum="2.0.0" IncludeMaximum="yes" IncludeMinimum="yes" OnlyDetect="no" Property="UPGRADE2X0X0"></UpgradeVersion>
  </Upgrade>

  <Property Id="FOODIR">
    <RegistrySearch Id="FooPath" Type="directory" Root="HKLM" Key="Software\Foo" Name="InstallPath"></RegistrySearch>
  </Property>

  <Directory Id="TARGETDIR" Name="SourceDir">
    <Directory Id="ProgramFilesFolder">
      <Directory Id="RefAssemb" Name="Reference Assemblies">
        <Directory Id="FOODIR" Name="Foo">
          <Component Id="FooLibPath" Guid="Guid 3">
            <RegistryKey Root="HKLM" Key="Software\Foo" Action="createAndRemoveOnUninstall">
              <RegistryValue Name="InstallPath" Type="string" Value="[FOODIR]" KeyPath="yes"></RegistryValue>
            </RegistryKey>
          </Component>
          <Directory Id="FOOVERSION" Name="v2.0.1">
            <Component Id="Foo_VSFile" Guid="Guid 4">
              <File Id="Foo_DLL" Source="$(sys.CURRENTDIR)2.0.1\Foo.dll" KeyPath="yes"></File>
            </Component>
            <Component Id="Foo_VSRegKey" Guid="Guid 5">
              <RegistryKey Root="HKLM" Key="SOFTWARE\Microsoft\.NETFramework\v3.5\AssemblyFoldersEx\Foo v2.0.1" Action="createAndRemoveOnUninstall">
                <RegistryValue Type="string" Value="[FOOVERSION]" KeyPath="yes"></RegistryValue>
              </RegistryKey>
            </Component>
            <Directory Id="FOOGAC" Name="GAC">
              <Component Id="Foo_GAC" Guid="Guid 6">
                <File Id="Foo" Source="$(sys.CURRENTDIR)2.0.1\Foo.dll" KeyPath="yes" Assembly=".net"></File>
              </Component>
              <Component Id="Foo_Policy_2x0x1" Guid="Guid 7">
                <File Id="Foo_PolicyDLL" Source="$(sys.CURRENTDIR)2.0.1\policy.2.0.Foo.dll" KeyPath="yes" Assembly=".net"></File>
                <File Id="Foo_PolicyConfig" Source="$(sys.CURRENTDIR)2.0.1\policy.2.0.Foo.config" CompanionFile="Foo_PolicyDLL"></File>
              </Component>
            </Directory>
          </Directory>
        </Directory>
      </Directory>
    </Directory>
  </Directory>

  <Feature Id="ProductFoo" Level="1">

      <ComponentRef Id="Foo_GAC"/>

      <Feature Id="Foo_VSSupport" Level="1">
        <ComponentRef Id="FooLibPath"/>
        <ComponentRef Id="Foo_VSFile"/>
        <ComponentRef Id="Foo_VSRegKey"/>
      </Feature>

      <Feature Id="Foo_Policy_v2x0x1" Level="0">
        <ComponentRef Id="Foo_Policy_2x0x1"/>
        <Condition Level="1">UPGRADE2X0X0</Condition>
      </Feature>

  </Feature>

</Product>
4

1 に答える 1

1

製品のアンインストール後に孤立した機能/コンポーネントを削除しても安全ですか?

いいえ、ちがいます。削除しただけでは、そのコンポーネントの登録情報がマシンに残ります。

また、孤立していると思われるコンポーネントをまだ参照しているものを確認する方法はありますか?

あまり。しかし、あなたのコンポーネントの 1 つを参照しているものがある場合、それはあなたが開発した別の製品か、正しくアンインストールされなかった現在の製品の古いバージョンである可能性が最も高いです。

ランダムな製品がコンポーネントまたはアセンブリを参照することはほとんどありません。

また、インストーラーを修正して、今後これが発生しないようにするにはどうすればよいですか?

古いコンポーネントをアンインストールして新しいコンポーネントをインストールするメジャー アップグレードを使用します。特別なポリシー ファイルや、条件付きのインストールや削除はありません。

一度に複数のバージョンの Foo ライブラリをマシンにインストールでき、それぞれが Foo の下の適切なフォルダーに配置されます。

なんで?製品が 1 つの場合は、メジャー アップグレードを使用できます。このようにして、ユーザーはアセンブリの 1 つのバージョンのみを使用して 1 つのバージョンのみをインストールできます。

バージョン管理されたアセンブリを並べてインストールすることは、異なる製品に対してのみ意味があります。

バグ修正が唯一の変更であるため、Foo 2.0.0 の参照を Foo 2.0.1 にリダイレクトするポリシー ファイルを GAC に追加することが決定されました。このポリシー ファイルは、新しい機能内の新しいコンポーネントとしてインストーラーに追加されました。

これはハックであり、おそらくこれが問題の原因です。新しくインストールしたものは、Foo 2.0.0 とともに古いバージョンをアンインストールしているはずです。

メジャー アップグレードは常にスタンドアロンで行う必要があります。

于 2011-09-15T18:00:56.807 に答える