9

WIXを使用して、単一の製品の複数の機能をインストールできるセットアッププロジェクトを作成しようとしています。機能ツリーに他の機能を再インストールせずに、インストールされている機能の1つ(インストールされている他の機能から独立している)を更新するにはどうすればよいですか?

たとえば、HelloWolrdというプロジェクト(HelloWolrdに戻る)を作成して、「Helloworld!」を(サプライズで)印刷できるようにしたいと考えています。画面上。これらのHelloWorldアプリケーションのうち、Hello World 1、Hello World 2、HelloWorld3の3つがあるとします。それぞれがHelloWorld1、2、または3の画面にそれぞれ印刷されます。私が欲しいのは、デフォルトでこれら3つの「機能」すべてをインストールするだけでなく、後で各機能を個別にアップグレードできるMSIを作成することです。

これが私のソリューションのレイアウトです:

ソリューションエクスプローラーhttp://img12.imageshack.us/img12/5671/solutionexplorerm.jpg

私のWIXProduct.wxsファイルは次のようになります。

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Id="ca484210-c719-4b2e-b960-45212d407c11" Name="HelloWorldInstaller" Language="1033" Version="1.0.0.0" Manufacturer="HelloWorldInstaller" UpgradeCode="68eeb8cb-9ef3-443c-870c-9b406129f7ff">
        <Package InstallerVersion="200" Compressed="yes" />

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

        <!-- Create Directory Structure -->
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder">
                <Directory Id="INSTALLLOCATION" Name="Hello World" />
            </Directory>
            <Directory Id="DesktopFolder" Name="Desktop"/>
        </Directory>

        <DirectoryRef Id="INSTALLLOCATION">
            <Component Id="HelloWorld1" Guid="6D1D9D33-DA17-4db3-8132-C39F32200C3A">
                <RegistryKey Root="HKCU" Key="Software\HelloWorldInstaller\HelloWorld1\Install" Action="createAndRemoveOnUninstall">
                    <RegistryValue Name="DTSC" Value="1" Type="integer" KeyPath="yes" />
                </RegistryKey>

                <File Id="HelloWorld1.exe" Name="$(var.HelloWorld1.TargetFileName)" Source="$(var.HelloWorld1.TargetPath)" DiskId="1" Checksum="yes">
                    <Shortcut Id="HelloWorld1ApplicationDesktopShortcut" Name="Hello World 1" Description="Hello World Application 1" Directory="DesktopFolder" WorkingDirectory="INSTALLLOCATION" />
                </File>

            </Component>
            <Component Id="HelloWorld2" Guid="B2D51F85-358B-41a7-8C45-B4BB341158F8">
                <RegistryKey Root="HKCU" Key="Software\HelloWorldInstaller\HelloWorld2\Install" Action="createAndRemoveOnUninstall">
                    <RegistryValue Name="DTSC" Value="1" Type="integer" KeyPath="yes" />
                </RegistryKey>

                <File Id="HelloWorld2.exe" Name="$(var.HelloWorld2.TargetFileName)" Source="$(var.HelloWorld2.TargetPath)" DiskId="1" Checksum="yes">
                    <Shortcut Id="HelloWorld2ApplicationDesktopShortcut" Name="Hello World 2" Description="Hello World Application 2" Directory="DesktopFolder" WorkingDirectory="INSTALLLOCATION" />
                </File>
            </Component>
            <Component Id="HelloWorld3" Guid="A550223E-792F-4169-90A3-574D4240F3C4">
                <RegistryKey Root="HKCU" Key="Software\HelloWorldInstaller\HelloWorld3\Install" Action="createAndRemoveOnUninstall">
                    <RegistryValue Name="DTSC" Value="1" Type="integer" KeyPath="yes" />
                </RegistryKey>

                <File Id="HelloWorld3.exe" Name="$(var.HelloWorld3.TargetFileName)" Source="$(var.HelloWorld3.TargetPath)" DiskId="1" Checksum="yes">
                    <Shortcut Id="HelloWorld3ApplicationDesktopShortcut" Name="Hello World 3" Description="Hello World Application 3" Directory="DesktopFolder" WorkingDirectory="INSTALLLOCATION" />
                </File>
            </Component>
        </DirectoryRef>

        <Feature Id="HelloWorld1Feature" Title="Hello World 1" Level="1">
            <ComponentRef Id="HelloWorld1"/>
        </Feature>
        <Feature Id="HelloWorld2Feature" Title="Hello World 2" Level="1">
            <ComponentRef Id="HelloWorld2"/>
        </Feature>
        <Feature Id="HelloWorld3Feature" Title="Hello World 3" Level="1">
            <ComponentRef Id="HelloWorld3"/>
        </Feature>

    </Product>
</Wix>

これがビルドされると、期待どおりの機能がインストールされます。ただし、HelloWorld1.vbに変更を加えて再コンパイルする場合は、すべてではなく、その機能のみを再インストール(アップグレード)できるようにしたいと思います。

1つのファイルを更新し、ソリューションを再構築してからmsiをインストールしようとすると、次のエラーが発生します。

MSIエラーhttp://img696.imageshack.us/img696/849/anotherversionisinstall.jpg

機能をアンインストールしてアップグレードコードを使用できるようにコードを更新しましたが、すべての機能がアンインストールされ、すべてが再インストールされました。


-実世界のアプリケーション-

これに対する実際のアプリケーションは、サービス/スケジュールされたタスクとして定期的に実行される複数のサポートアプリケーションを必要とする大規模なソフトウェアパッケージです。これらのサポートアプリを1つのMSIにインストールして、各exeを個別に展開するという悪夢を回避できるようにしたいと思います。exeの1つに更新があれば、そのexeを手動でコンパイルしてロールアウトできることは知っていますが、完全に再現可能な方法でこれを実行したいと思います。

どんな助けでも適用されるでしょう、

ありがとうございました!

編集:

GoogleCodeからダウンロードするためのソースを追加しました。再度、感謝します!

4

2 に答える 2

15

私はこれを理解し、他の人のために将来参照するためにここに答えを投稿すると思いました。それで、私は問題を完全に説明しました、私は現実世界のシナリオのより深いところに行きます。

適度に大きなソフトウェアがあり、複数の異なるサーバーで実行される複数のサポートアプリケーションが必要です。現在のアップグレードの進行により、信頼できる方法でコードをアップグレードすることは適度に困難になっています。現在、自己解凍型exeを使用して、コードをさまざまなサーバーにロールアウトしています。この問題は、サポートするアプリケーションが非常に多く、アプリケーションが正しい構成設定で正しくインストールされていることを確認するのが困難になる場合などに発生します。この問題を解決するために、それぞれを圧縮する代わりに、サポートするアプリケーションについては、インフラストラクチャチームが特定のサポートアプリケーションのセットを各マシンにインストールできるようにする単一のインストーラー(MSI)を作成します。大きな変更(たとえば、1.0から2.0)がある場合は、完全なアップグレードインストールを実行します(つまり、すべてのサービス/プロセスを停止、アンインストール、インストール、および開始する必要があります)。小さな変更がある場合は、他のアプリケーションに触れることなく、影響を受けるサービス/プロセスを停止して再インストールするだけで済みます。さて、私は十分にとりとめのないです、ソリューション:

シナリオではショートカットは実際には必要ないため、WIXProduct.wxsを変更してショートカットを削除しました。更新されたwxsファイルは次のとおりです。

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
 <Product Id="13C373D3-5C27-487e-A020-C2C89E4607B1" Name="HelloWorldInstaller" Language="1033" Version="1.0.0.0"
      Manufacturer="HelloWorldInstaller" UpgradeCode="E7CB3C76-4D51-48a8-BFB4-6D11B2E2E65B">

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

  <Media Id="1" Cabinet="product.cab" EmbedCab="yes" />
  <FeatureRef Id="HelloWorld1Feature" />
  <FeatureRef Id="HelloWorld2Feature" />
  <FeatureRef Id="HelloWorld3Feature" />
 </Product>

 <Fragment>
  <Directory Id="TARGETDIR" Name="SourceDir">
   <Directory Id="ProgramFilesFolder">
    <Directory Id="INSTALLLOCATION" Name="Hello World" />
   </Directory>
   <Directory Id="DesktopFolder" Name="Desktop"/>
  </Directory>
 </Fragment>

 <Fragment>
  <DirectoryRef Id="INSTALLLOCATION">
   <Directory Id="HelloWorld1Directory" Name="Hello World 1">
    <Component Id="HelloWorld1Component" Guid="6D1D9D33-DA17-4db3-8132-C39F32200C3A">
     <File Id="HelloWorld1.exe" Name="HelloWorld1.exe" Source="HelloWorld1.exe" DiskId="1" Checksum="yes" />    
    </Component>
   </Directory>
   <Directory Id="HelloWorld2Directory" Name="Hello World 2">
    <Component Id="HelloWorld2Component" Guid="B2D51F85-358B-41a7-8C45-B4BB341158F8">
     <File Id="HelloWorld2.exe" Name="HelloWorld2.exe" Source="HelloWorld2.exe" DiskId="1" Checksum="yes" />
    </Component>
   </Directory>
   <Directory Id="HelloWorld3Directory" Name="Hello World 3">
    <Component Id="HelloWorld3Component" Guid="A550223E-792F-4169-90A3-574D4240F3C4">
     <File Id="HelloWorld3.exe" Name="HelloWorld3.exe" Source="HelloWorld3.exe" DiskId="1" Checksum="yes" />
    </Component>
   </Directory>
  </DirectoryRef>
 </Fragment>

 <Fragment>
  <Feature Id="HelloWorld1Feature" Title="Hello World 1" Level="1">
   <ComponentRef Id="HelloWorld1Component"/>
  </Feature>
 </Fragment>
 <Fragment>
  <Feature Id="HelloWorld2Feature" Title="Hello World 2" Level="1">
   <ComponentRef Id="HelloWorld2Component"/>
  </Feature>
 </Fragment>
 <Fragment>
  <Feature Id="HelloWorld3Feature" Title="Hello World 3" Level="1">
   <ComponentRef Id="HelloWorld3Component"/>
  </Feature>
 </Fragment>
</Wix>

これに伴い、マイナーアップグレードでは、コンポーネントのパッチのリリースを検討します。

たとえば、1、2、および3の3つのコンポーネントを持つProductAがあるとします。これらの3つのコンポーネントは、サービスまたはスケジュールされたタスクのいずれかとして実行する必要があります。当社の製品の性質上、コンポーネントの1つを更新または修正するためにすべてのサービスをシャットダウンすることはできません。したがって、バージョン1.0をインストールした後、コンポーネント2にバグが見つかったが、このバグに適用された修正によって1または3が影響を受けないようにする場合は、コンポーネント2のパッチをリリースします。したがって、コンポーネント2のみが影響を受けます。

上記の簡単な例では、HelloWorld1、HelloWorld2、およびHelloWorld3をソフトウェアアプリケーションの3つのコンポーネントとして使用しています。1つのMSIで3つすべてをインストールできるはずですが、インストールされている他のコンポーネントに影響を与えることなく、それぞれを個別に更新できるはずです。

そこで、これを実証するために、「Hello World 1!」、「Hello World 2!」、「Hello World3!」を表示する上記の3つのコンソールアプリケーションを作成しました。次に、最初のMSIをリリースした後、HelloWorld1に「HelloWorld 1!Updated」と言わせる必要がある「バグ」を見つけたとします。代わりは。これをシミュレートするために行うことは次のとおりです。

  1. コマンドプロンプトで次のコマンドを実行して、Product.wixobjを作成します
    candle.exe Product.wxs
    。candle.exeまたはいずれかのWIXコマンドを呼び出すには、WixインストールディレクトリがPATH変数に含まれている必要があることに注意してください。(PATH環境変数の更新に関する短いチュートリアル)また、Product.wxsファイルと同じディレクトリでコマンドを実行してください。
  2. 製品の最初のバージョンを作成します(たとえば1.0)。
    light.exe Product.wixobj -out ProductA-1.0.msi
  3. 次に、バグを見つけて(HelloWorld1の出力を「HelloWorld 1!Updated。」に変更します)、アセンブリバージョンとファイルバージョンを更新します。これは、WIXがexeの違いを判断する方法であるため重要です。
  4. 手順1と同じコマンドを実行します(適切な測定のため)。
    candle.exe Product.wxs
  5. 手順2とほぼ同じコマンドを実行します。
    light.exe Product.wixobj -out ProductA-1.1.msi
    これは1.0ではなくバージョン1.1であることに注意してください(これは更新されたコードを含むmsiです)。ただし、これをインストールするだけではなく、読み続けてください。
  6. これが楽しい部分です。次のコマンドで2つのMSIの違いを取得します。
    torch.exe -p -xi ProductA-1.0.wixpdb ProductA-1.1.wixpdb -out Diff.WixMst
  7. 次に、これからパッチファイルを作成します(Patch.wxsについては以下で説明します)。
    candle.exe Patch.wxs
  8. 次に、次のコマンドを使用してWixMspファイルを作成します。
    light.exe Patch.wixobj -out Patch.WixMsp
  9. そして今、楽しい部分。次のコマンドでMSPファイルを作成します。
    pyro.exe Patch.WixMsp -out Patch.msp -t RTM Diff.Wixmst

これで、すべてが計画どおりに進んだ場合、2つのmsiファイルと1つのmspファイルが必要になります。最初のmsi(ProductA-1.0.msi)をインストールしてHelloWorld1.exeを実行すると、「Hello World1!」というメッセージが表示されます。楽しみのために(そして例として)、他の両方のアプリケーションを実行し、実行したままにします(私はそれらを開いたままにするためにストップを組み込みました)。そのexeに更新を適用するので、HelloWorld1.exeを閉じますが、そうしても、HelloWorld2.exeまたはHelloWorld3.exeには影響しません。ここでmsp(Patch.msp)ファイルをインストールしてから、HelloWorld1.exeを実行すると、「Hello World 1!Updated」という更新されたメッセージが表示されます。

さて、魔法のPatch.wxsファイルの場合:

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
 <Patch
   AllowRemoval="yes"
   Manufacturer="Dynamo Corp"
   MoreInfoURL="http://www.dynamocorp.com/"
   DisplayName="Sample Patch"
   Description="Small Update Patch"
   Classification="Update"
        >

  <Media Id="5000" Cabinet="RTM.cab">
   <PatchBaseline Id="RTM"/>
  </Media>

  <PatchFamilyRef Id="SamplePatchFamily"/>
 </Patch>

 <Fragment>
  <PatchFamily Id='SamplePatchFamily' Version='1.0.0' Supersede='yes'>
   <ComponentRef Id="HelloWorld1Component"/>
  </PatchFamily>
 </Fragment>
</Wix>

あまり見えませんね。さて、最も興味深い部分はこれらです:

  1. <PatchBaseline Id="RTM"/>-これは、パッチmsiの作成で使用されたことを思い出してください。「RTM」は、上記の最後のステップで参照されます。--t RTMこれらは一致する必要があります。
  2. <ComponentRef Id="HelloWorld1Component"/>-これにより、パッチが更新する正しいコンポーネント(この場合はHelloWorld1Component)を指し示します。

上記のコードは、Peter Marcuのブログからのものであるため、検索を行っている場合はおなじみのように思われるかもしれません:WiX:新しいパッチ構築システムを使用したパッチの構築-パート3

また、 Alex Shevchukのブログに大きく依存しました:MSIからWiXへ、パート8-メジャーアップグレード

「うわー、それはたくさんのステップです、なぜ誰かがこれほど多くのステップを実行するのですか?」と疑問に思っている場合は、(上記の)ハードワークが完了したら、これを統合ルーチンに移動する必要があることを覚えておいてください。そうです、統合、統合、統合!これはどうやるんですか?さて、それはもう少し研究であり、おそらくブログ投稿ですか?- おそらく。正しい方向に進むために、MSBuildとWindowsインストーラーXMLを使用したリリースの自動化に関するすばらしい記事を紹介します。

うわー、私はあなたがこれのすべて(あなたの2人全員)を読んで、そしてたくさん学んだことを望みます。これが私以外の誰かに役立つことを願っています。

ありがとうございました!

于 2009-11-18T00:16:28.187 に答える
0

Sounds like you figured out the upgrade scenario, now you just need to figure out Where to place RemoveExistingProducts in a major MSI upgrade so that features aren't reinstalled if they haven't changed :)

于 2009-11-16T22:51:05.510 に答える