2

製品をインストールするプロジェクトをビルドするために WiX 3.8 を使用しています。インストーラーは基本的に完了です。パッケージによってインストールされるプログラムの 1 つは、頻繁に更新されるサード パーティによる dll に依存しています。ばかばかしいことに、dll のバージョン番号は定期的に変更されます。最初にインストーラー プロジェクトを作成したとき、ファイル名の変更をサポートすることを考慮せず、すべてのコンポーネントを手動で作成しました。

この動作は将来的に変更する必要があります。私の理解が正しければ、 HeatDirectory Taskを使用して、ファイルのコンポーネントを自動的に生成できます。動作している HeatDirectory タスクを使用してサンプル プロジェクトを作成しました。しかし、HeatDirectory タスクが生成する出力と、私が過去に使用してきた手動で作成したコンポーネントとの間には、いくつかの矛盾があります。

私は、HeatDirectory タスクが私の手動アプローチと同じ出力を可能な限り生成することを望んでいます。以下は、2 つのコンポーネントのコードです。最初は手動で作成され、次に HeatDirectory タスクによって作成されます。

手動で作成されたコンポーネント:

<ComponentGroup Id="ThirdParty.v13.2" Directory="INSTALLFOLDER">
<Component 
  Id="CMP_ThirdParty.v13.2.dll" 
  Guid="AC5E00F0-B458-4272-B132-F13594ED4916">
  <File 
    Id="ThirdParty.v13.2.dll" 
    Name="ThirdParty.v13.2.dll" 
    Source="ComponentsDir\ThirdParty\ThirdParty.v13.2.dll" 
    KeyPath="yes" 
    Assembly=".net" 
    AssemblyApplication="ThirdParty.v13.2.dll" 
    AssemblyManifest="ThirdParty.v13.2.dll" 
    Compressed="no" 
    DiskId="$(var.ThirdPartyDiskId)"/>
</Component>
<Component 
  Id="CMP_ThirdParty.v13.2.xml" 
  Guid="64AC3F5F-38E9-41EC-B714-636F5D9C0CB4">
  <File 
    Id="ThirdParty.v13.2.xml" 
    Name="ThirdParty.v13.2.xml" 
    Source="Source="ComponentsDir\ThirdParty\ThirdParty.v13.2.xml" 
    KeyPath="yes" 
    Compressed="no" 
    DiskId="$(var.ThirdPartyDiskId)"/>
</Component>
</ComponentGroup>

HeatDirectory タスク生成コード:

<ComponentGroup Id="Files">
<Component 
  Id="cmp9D064A733360960E07277CFD9AB84AF1" 
  Directory="INSTALLFOLDER" 
  Guid="*">
  <File 
    Id="filD5DCB6E091D2D12303E2E80B0B767438" 
    KeyPath="yes" 
    Source="$(var.Path)\ThirdParty.v13.2.dll"/>
</Component>
<Component 
  Id="cmpA8681A63A8A4991D18824BA17E4CA4BF" 
  Directory="INSTALLFOLDER" 
  Guid="*">
  <File 
    Id="fil17554B3CD0E576337AEC758831009938" 
    KeyPath="yes" 
    Source="$(var.Path)\ThirdParty.v13.2.xml"/>
</Component>
</ComponentGroup>

上記の出力を生成するコードは次のとおりです。

<Target Name="BeforeBuild">
<HeatDirectory 
  DirectoryRefId="INSTALLFOLDER" 
  OutputFile="Files.wxs" 
  Directory="S:\omePath" 
  SuppressRootDirectory="true" 
  ToolPath="$(WixToolPath)" 
  AutogenerateGuids="true" 
  ComponentGroupName="Files" 
  PreprocessorVariable="var.Path">
</HeatDirectory>
</Target>

ここで、変更したい HeatDirectory タスク生成コードの特性を書き留めておきます。

  1. componentgroup 内のすべてのコンポーネントにはDirectory属性があります。ComponentGroup親に属性を持たせDirectory、すべての子コンポーネントでそれを省略したい。
  2. 静的ガイドが必要です。
  3. Idコンポーネントの属性を、接頭辞とCMPそれに続くファイル名で構成したいと考えています。プロジェクトに同じファイル名を持つ 2 つのファイルが存在できないことは理解していますが、そうではないことはわかっています。タスクによって生成された不可解な識別子は必要ありません。
  4. コンポーネントのFile子項目が質素すぎます。Nameファイルの現在の名前であるすべてのファイルの属性を作成するために、HeatDirectoy タスクが必要です。次に、Compressed属性に値を追加し、何らかの方法でタスクで指定できる変数値を追加する必要がありますnoDiksId
  5. 収集されたファイルが dll の場合、タスクは属性Asssemblyに value を.net追加し、収集AssemblyApplicationされたファイルの名前をその値として、また収集されたファイルの名前をその値として追加する必要AssemblyManifestがあります。

HeatDirectory タスクでこれを達成することは可能ですか?

4

1 に答える 1

2

HeatDirectory タスクの出力を操作するための答えは、XSLT を使用することです。HeatDirectory タスクでは、TransformsXSLT 命令を含むファイルを指す属性を指定できます。私が求めていた出力を実現するには、次の XSLT コードを使用できます。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:wix="http://schemas.microsoft.com/wix/2006/wi"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  exclude-result-prefixes="msxsl">

  <xsl:output
    method="xml"
    indent="yes"/>
  <xsl:variable name="ComponentGroup-Id" select="//wix:ComponentGroup/@Id"/>
  <xsl:variable name="DestinationFolder" select="//wix:Component[1]/@Directory"/>
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select ="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="//wix:Directory">
    <xsl:variable name="DirName" select="@Name" />
    <xsl:copy>
      <xsl:attribute name="Id">
        <xsl:value-of select="$ComponentGroup-Id"/>
        <xsl:text>_</xsl:text>
        <xsl:value-of select="$DirName"/>
      </xsl:attribute>
      <xsl:attribute name="Name">
        <xsl:value-of select="$DirName"/>
      </xsl:attribute>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="//wix:ComponentGroup">
    <xsl:copy>
      <xsl:attribute name="Id">
        <xsl:value-of select="$ComponentGroup-Id"/>
      </xsl:attribute>
      <xsl:attribute name="Directory">
        <xsl:value-of select="$DestinationFolder"/>
      </xsl:attribute>
      <xsl:apply-templates />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="//wix:Component">
    <xsl:variable name="FilePath" select="current()/wix:File/@Source" />
    <xsl:variable name="FileName" select="substring-after($FilePath,'\')" />
    <xsl:variable name="Guid" select="@Guid" />
    <xsl:copy>
      <xsl:attribute name="Id">
        <xsl:text>CMP_</xsl:text>
        <xsl:choose>
          <xsl:when test="contains($FileName,'\')">
            <xsl:value-of select="substring-after($FileName,'\')"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="$FileName"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>
      <xsl:attribute name="Guid">
        <xsl:value-of select="$Guid"/>
      </xsl:attribute>
      <xsl:apply-templates />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="//wix:File">
    <xsl:variable name="FilePath" select="@Source" />
    <xsl:variable name="FileName" select="substring-after($FilePath,'\')" />
    <xsl:copy>
      <xsl:attribute name="Id">
        <xsl:choose>
          <xsl:when test="contains($FileName,'\')">
            <xsl:value-of select="substring-after($FileName,'\')"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="$FileName"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>
      <xsl:attribute name="KeyPath">
        <xsl:text>yes</xsl:text>
      </xsl:attribute>
      <xsl:attribute name="Source">
        <xsl:value-of select="$FilePath"/>
      </xsl:attribute>
      <xsl:if test="contains($FileName,'.dll')">
        <xsl:attribute name="Assembly">.net</xsl:attribute>
        <xsl:attribute name="AssemblyApplication">
          <xsl:choose>
            <xsl:when test="contains($FileName,'\')">
              <xsl:value-of select="substring-after($FileName,'\')"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="$FileName"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:attribute>
        <xsl:attribute name="AssemblyManifest">
          <xsl:choose>
            <xsl:when test="contains($FileName,'\')">
              <xsl:value-of select="substring-after($FileName,'\')"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="$FileName"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:attribute>
      </xsl:if>
      <xsl:attribute name="Compressed">
        <xsl:text>no</xsl:text>
      </xsl:attribute>
      <xsl:attribute name="DiskId">
        <xsl:text>$(var.SomeDiskID)</xsl:text>
      </xsl:attribute>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>
于 2014-03-12T12:53:24.890 に答える