使用 WiX 工具集部署多个 WCF Web 服务 - 错误的 svc 文件

Posted

技术标签:

【中文标题】使用 WiX 工具集部署多个 WCF Web 服务 - 错误的 svc 文件【英文标题】:Deploy multiple WCF Webservices with WiX Toolset - Wrong svc files 【发布时间】:2013-10-22 10:33:11 【问题描述】:

我正在尝试使用 VS2012 中的 WIX Toolset 3.7 为我的 WFC 服务创建安装程序。所有服务都有相同的结构:

service.svc 只是链接到特定的类

<%@ ServiceHost Language="C#" Debug="true"
    Service="LandwehrServices.Service.Vorlage.ServiceOption" 
    Factory="ServiceCreator.DigestAuthenticationHostFactory" %>

dll 正在正确安装,但所有文件夹都包含相同的 service.svc(第一个安装的服务)文件...

这是我的Product.wxs

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="020f2a79-d085-4c05-b49d-a09300e8a144"
       Name="!(loc.ProductName)"
       Language="1031" 
       Version="1.0.0.0"
       Manufacturer="!(loc.CompanyName)" 
       UpgradeCode="a0bbe6c8-1658-43e4-9cf8-51d6bbdf84d2">

  <Package InstallerVersion="200" Compressed="yes"
         Languages="!(loc.LANG)"
         Manufacturer="!(loc.CompanyName)" Comments="!(loc.Comments)"
         Description="!(loc.Description)" Keywords="!(loc.Keywords)"/>

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

    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder">
        <Directory Id="INSTALLLOCATION" Name="!(loc.ProductName)">
          <Directory Id="INSTALLLOCATION.Option" Name="Service.Option" />
          <Directory Id="INSTALLLOCATION.Personal" Name="Service.Personal" />
          <Directory Id="INSTALLLOCATION.Postbox" Name="Service.Postbox" />
        </Directory>
      </Directory>
    </Directory>

    <Feature Id="ProductFeature" Title="!(loc.ProductName)" Level="1">
      <ComponentGroupRef Id="Option_Project" />
      <ComponentGroupRef Id="Personal_Project" />
      <ComponentGroupRef Id="Postbox_Project" />
    </Feature>
</Product>
</Wix>

还有我在.wixdproj 中的BeforeBuild 条目

<Target Name="BeforeBuild">
<MSBuild Projects="%(ProjectReference.FullPath)"
         Targets="Package"
         Properties="Configuration=$(Configuration);Platform=AnyCPU"
         Condition="'%(ProjectReference.WebProject)'=='True'" />
<ItemGroup>
  <LinkerBindInputPaths Include="%(ProjectReference.RootDir)%(ProjectReference.Directory)obj\$(Configuration)\Package\PackageTmp\" />
</ItemGroup>
<HeatDirectory OutputFile="%(ProjectReference.Filename).wxs"
               Directory="%(ProjectReference.RootDir)%(ProjectReference.Directory)obj\$(Configuration)\Package\PackageTmp\"
               DirectoryRefId="INSTALLLOCATION.%(ProjectReference.Filename)"
               ComponentGroupName="%(ProjectReference.Filename)_Project"
               AutogenerateGuids="true" SuppressCom="true" SuppressFragments="true" SuppressRegistry="true"
               SuppressRootDirectory="true" ToolPath="$(WixToolPath)" Condition="'%(ProjectReference.WebProject)'=='True'" />
</Target>

有什么想法吗?这是我第一次使用 WIX...

【问题讨论】:

...\Mobile\Service.Personal\obj\Debug\Package\PackageTmp 的源文件包含正确的代码。如果我将service.svc 重命名为servicePersonal.svc 之类的个人名称,它就可以正常工作。安装过程中是否有临时目录用于复制文件? 【参考方案1】:

好的。这已经为我解决了这个问题。

强制使用命名绑定路径调用链接器

我添加了以下项目组,其中项目指向两个包。

<ItemGroup>
    <BindInputPaths Include="..\MyProject1\obj\Debug\Package\PackageTmp">
      <BindName>MyProject1</BindName>
      <InProject>false</InProject>
    </BindInputPaths>
    <BindInputPaths Include="..\MyProject2\obj\Debug\Package\PackageTmp">
      <BindName>MyProject2</BindName>
      <InProject>false</InProject>
    </BindInputPaths>
</ItemGroup>

在包含 LinkerBindInputPaths 元素的预构建步骤中删除项目组。

在 Visual Studio 输出窗口中验证这一点。 Light.exe 命令行现在应该具有命名的绑定路径。

-b "MyProject1=D:\Projects\...\MyProject1\obj\Debug\Package\PackageTmp" 
-b "MyProject2=D:\Projects\...\MyProject2\obj\Debug\Package\PackageTmp"

在收获输出中使用命名绑定路径

我试图让 HeatDirectory 任务生成此输出,但最后只是使用 XSLT 转换来更新 SourceDir 部分以使用 bindpath 变量。

更新 Wix 项目以在通过 XSLT 转换进行管道传输之前将 Heat 输出定向到 tmp 文件。

<HeatDirectory OutputFile="%(ProjectReference.Filename)-temp.wxs" 
               Directory="%(ProjectReference.RootDir)%(ProjectReference.Directory)obj\$(Configuration)\Package\PackageTmp\" 
               DirectoryRefId="%(ProjectReference.Name)InstallFolder" 
               ComponentGroupName="%(ProjectReference.Name)_Project" 
               AutogenerateGuids="true" 
               SuppressCom="true" 
               SuppressFragments="true" 
               SuppressRegistry="true" 
               SuppressRootDirectory="true" 
               ToolPath="$(WixToolPath)" 
               Condition="'%(ProjectReference.WebProject)'=='True'" />

<XslTransformation XmlInputPaths="%(ProjectReference.Filename)-temp.wxs" 
                   XslInputPath="XslTransform.xslt" 
                   OutputPaths="%(ProjectReference.Filename).wxs" 
                   Condition="'%(ProjectReference.WebProject)'=='True'" />

将 XSLT 转换包含到 Wix 项目中 (XslTransform.xslt)

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

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template name="string-replace-all">
    <xsl:param name="text" />
    <xsl:param name="replace" />
    <xsl:param name="by" />
    <xsl:choose>
      <xsl:when test="contains($text, $replace)">
        <xsl:value-of select="substring-before($text,$replace)" />
        <xsl:value-of select="$by" />
        <xsl:call-template name="string-replace-all">
          <xsl:with-param name="text" select="substring-after($text,$replace)" />
          <xsl:with-param name="replace" select="$replace" />
          <xsl:with-param name="by" select="$by" />
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$text" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template match="@Source['SourceDir']" >

    <xsl:attribute name="Source">

      <xsl:variable name="projectName">
        <xsl:value-of select="/wix:Wix/wix:Fragment/wix:ComponentGroup/@Id"/>
      </xsl:variable>

      <xsl:call-template name="string-replace-all">
        <xsl:with-param name="text" select="." />
        <xsl:with-param name="replace" select="'SourceDir'" />
        <xsl:with-param name="by" select="concat('!(bindpath.',$projectName,')')" />
      </xsl:call-template>

    </xsl:attribute>

  </xsl:template>

</xsl:stylesheet>

Heat 输出应使用 ComponentGroup 名称作为绑定路径变量。

<Component Id="..." Guid="*">
    <File Id="..." KeyPath="yes" Source="!(bindpath.MyProject1)\Default.aspx" />
</Component>

构建后,我在 Orca 中验证了 MSI。在修复之前 Orca 列出了我的文件的两个版本,它们都具有相同的字节大小。现在它列出了两个版本及其适当的大小。

【讨论】:

天啊,我不敢相信这真的有效。我花了 2 天时间试图找到解决这个问题的方法。非常感谢^^ 不用担心。它也让我头疼。【参考方案2】:

我目前有完全相同的问题。我相信它是由链接器(Light)绑定路径引起的。他们获取两个打包的输出文件夹并将它们组合起来。查看 VS 输出中的链接器命令行,它使用 –b 标志来指定绑定路径。当有多个路径时,我认为它应该使用命名路径。

http://wixtoolset.org/documentation/manual/v3/howtos/general/specifying_source_files.html

C:\Program Files (x86)\WiX Toolset v3.7\bin\Light.exe 
-out "D:\Projects\...\Setup.msi" 
-pdbout "D:\Projects\...\Setup.wixpdb" 
-b "D:\Projects\...\MyProject1\obj\Debug\Package\PackageTmp\\" 
-b "D:\Projects\...\MyProject2\obj\Debug\Package\PackageTmp\\" 
-cultures:en-us -ext "C:\Program Files (x86)\WiX Toolset v3.7\bin\\WixUtilExtension.dll" 
-ext "C:\Program Files (x86)\WiX Toolset v3.7\bin\\WixIIsExtension.dll" 
-ext "C:\Program Files (x86)\WiX Toolset v3.7\bin\\WixUIExtension.dll" 
-loc WebAppInstallDlg_en-us.wxl -contentsfile obj\Debug\Setup.wixproj.BindContentsFileListen-us.txt 
-outputsfile obj\Debug\Setup.wixproj.BindOutputsFileListen-us.txt 
-builtoutputsfile obj\Debug\Setup.wixproj.BindBuiltOutputsFileListen-us.txt 
-wixprojectfile "D:\Projects\...\Setup.wixproj" obj\Debug\MyProject1.wixobj obj\Debug\MyProject2.wixobj obj\Debug\SetupUI.wixobj obj\Debug\Setup.wixobj

我认为解决方案是使用命名绑定路径。但是,我还没有设法在我的预构建步骤中找到指定命名绑定路径的方法。我的预构建步骤与您的相同,因此我试图弄清楚如何将 LinkerBindInputPaths 部分修改为使用的名称,如下所示。

<File Source="!(bindpath.foo)bar\baz.txt" />
<File Source="!(bindpath.bar)baz\foo.txt" />

light -b foo=C:\foo\ -b bar=C:\bar\ -b foo=D:\

安迪。

【讨论】:

以上是关于使用 WiX 工具集部署多个 WCF Web 服务 - 错误的 svc 文件的主要内容,如果未能解决你的问题,请参考以下文章

为每个 IIS 应用程序部署单个或多个 WCF 服务?

WCF Web 服务未部署在 localhost ... web.config ... 端点上

使用 wix 工具集安装多个 exe

使用 http 和 https 绑定/端点部署 WCF 服务

WiX“服务安装”究竟是如何在内部工作的?

wix的WIX简介