使用 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 文件的主要内容,如果未能解决你的问题,请参考以下文章
WCF Web 服务未部署在 localhost ... web.config ... 端点上