【问题标题】:WIX 3.6 Installer - Visual Studio 2010 (HeatDirectory)WIX 3.6 安装程序 - Visual Studio 2010 (HeatDirectory)
【发布时间】:2012-05-26 02:30:51
【问题描述】:

我正在为 Web 服务开发 WIX 3.6 安装程序。但是我在尝试使用 HeatDirectory 来获取所有必要的输出时遇到了一个问题,无论我尝试什么,每个获取的文件都会出现以下错误:

系统找不到文件'SourceDir\Some.dll...'

WcfService.wxs 中出现错误;奇怪的是 WcfService.wxs 是由我的项目文件中的 heatdirectory 部分自动创建的(如下)。 如果它必须首先知道它们在哪里来创建 WcfService.wxs,它怎么能说它找不到这些 .dll? 这些错误甚至在我下载并构建一个我读过的任何一篇教程中的 WIX 示例项目(原样)。

目标:尽可能多地自动化 .dll 包含(即利用收集来处理依赖项项目等)

我正在运行 Win 7 64bit,项目是 .NET 4。

Product.wxs:

    <?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Product Id="*" Name="CompleteInstall" Language="1033" Version="1.0.0.0" Manufacturer="Technologies" UpgradeCode="b2ae6aa5-263f-4f9a-a250-8599a7f2cb03">
    <Package InstallerVersion="200" Compressed="yes" />

    <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
    <MediaTemplate />

    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFiles64Folder">
        <Directory Id="CommonDir1" Name="Common Directory 1">
          <Directory Id="CommonDir2" Name="Common Directory 2">
            <Directory Id="INSTALLFOLDER" Name="Install Directory"/>
          </Directory>
        </Directory>
      </Directory>
    </Directory>

    <Feature Id="ProductFeature" Title="CompleteInstall" Level="1">
      <ComponentGroupRef Id="WcfService_Project" />
    </Feature>

    <Property Id="WIXUI_INSTALLDIR">INSTALLFOLDER</Property>
    <UIRef Id="WixUI_InstallDir" />
  </Product>
</Wix>

项目文件:

<Target Name="BeforeBuild">
    <MSBuild Projects="%(ProjectReference.FullPath)" Targets="Build" Properties="Configuration=$(Configuration);Platform=x86" Condition="'%(ProjectReference.ContentProject)'=='True'" />
    <PropertyGroup>
      <LinkerBaseInputPaths>%(ProjectReference.RootDir)%(ProjectReference.Directory)bin\$(Platform)\$(Configuration)\</LinkerBaseInputPaths>
    </PropertyGroup>
    <HeatDirectory OutputFile="%(ProjectReference.Filename)-temp.xml" 
                   Directory="%(ProjectReference.RootDir)%(ProjectReference.Directory)bin\$(Platform)\$(Configuration)\"
                   DirectoryRefId="INSTALLFOLDER" 
                   ComponentGroupName="%(ProjectReference.Filename)_Project"
                   SuppressCom="true" 
                   SuppressFragments="true" 
                   SuppressRegistry="true"
                   SuppressRootDirectory="true" 
                   AutoGenerateGuids="false" 
                   GenerateGuidsNow="true" 
                   ToolPath="$(WixToolPath)" 
                   Condition="'%(ProjectReference.ContentProject)'=='True'" />
    <XslTransformation XmlInputPaths="%(ProjectReference.Filename)-temp.xml"
                       XslInputPath="XslTransform.xslt" 
                       OutputPaths="%(ProjectReference.Filename).wxs" 
                       Condition="'%(ProjectReference.ContentProject)'=='True'" />
  </Target>

WcfService.wxs:

<?xml version="1.0" encoding="utf-8"?><Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <DirectoryRef Id="INSTALLFOLDER">
            <Component Id="cmpE6EBA3D8D6D4DB0C93E73200C78DCC51" Guid="{C88B5CF9-8807-45DF-AA6F-732437B74BB6}">
                <File Id="fil0118BBA61671E80581CA9C9AA6DD3E8D" KeyPath="yes" Source="SourceDir\Some.dll" />
            </Component>
        </DirectoryRef>
    </Fragment>
    <Fragment>
        <ComponentGroup Id="WcfService_Project">
            <ComponentRef Id="cmpE6EBA3D8D6D4DB0C93E73200C78DCC51" />
        </ComponentGroup>
    </Fragment>
</Wix>

【问题讨论】:

  • 你能发布完整的 wxs 文件吗?可能您没有为 Some.dll 输入正确的目录...
  • @Wimmel,我已经用完整的 wxs 更新了原始帖子。谢谢!
  • @Wimmel,请记住,我说过我从多个来源下载的示例项目也会出现同样的问题。
  • 你参考WcfService_Project,应该是另一个文件作为片段。参见例如here。在链接的问题中使用Source="PathToFile"PathToFile 应该指向一个现有文件。
  • @Wimmel,这实际上是对来自收获的热目录的 wxs 的引用。请看我上面的更新,我已经为你添加了那个 wxs。旁注:我还看到了您在发布之前提供的示例。感谢您迄今为止的帮助,我真的很感激。

标签: visual-studio-2010 wix windows-installer wix3.6 heat


【解决方案1】:

问题是缺少 HeatDirectory PreprocessorVariable 属性。我在我的 wixproj 文件中添加了以下内容,解决了这个问题:

<PropertyGroup>
  <DefineConstants>BasePath=%(ProjectReference.RootDir)%(ProjectReference.Directory);</DefineConstants>
</PropertyGroup>
<HeatDirectory OutputFile="%(ProjectReference.Filename).wxs" 
               DirectoryRefId="INSTALLFOLDER" 
               Directory="%(ProjectReference.RootDir)%(ProjectReference.Directory)"
               ComponentGroupName="%(ProjectReference.Filename)_Project"
               SuppressCom="true"
               SuppressFragments="true"
               SuppressRegistry="true"
               SuppressRootDirectory="true"
               AutoGenerateGuids="false"
               GenerateGuidsNow="true"
               ToolPath="$(WixToolPath)"
               Condition="'%(ProjectReference.ContentProject)'=='True'" 
               PreprocessorVariable="var.BasePath"/>

如您所见,我需要首先定义一个本地使用的常量变量。我将变量设置为我的 WCF 项目的根路径。其次,我将该变量用作我的 PreprocessorVariable。最后,我能够动态/递归地收集从 MsBuild 生成的文件。下一步:排除不必要的文件。我会参考这个link

请看下面我完整的wixproj:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
    <ProductVersion>3.5</ProductVersion>
    <ProjectGuid>{4005592f-cc0e-41a3-8e64-33b2824e7fd9}</ProjectGuid>
    <SchemaVersion>2.0</SchemaVersion>
    <OutputName>MyWCF.WCF.Webservice</OutputName>
    <OutputType>Package</OutputType>
    <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
    <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
    <OutputPath>bin\$(Configuration)\</OutputPath>
    <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
    <OutputPath>bin\$(Configuration)\</OutputPath>
    <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="MyWCF.WcfService.wxs" />
    <Compile Include="IISConfig.wxs" />
    <Compile Include="InstallUi.wxs" />
    <Compile Include="Product.wxs" />
    <Compile Include="UIDialogs.wxs" />
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\MyWCF.WcfService\MyWCF.WcfService.csproj">
      <Name>MyWCF.WcfService</Name>
      <Project>{8e528b38-2826-4793-a66d-f6ff181e1139}</Project>
      <Private>True</Private>
      <RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
      <RefTargetDir>INSTALLFOLDER</RefTargetDir>
      <ContentProject>True</ContentProject>
      <DoNotHarvest>True</DoNotHarvest>
      <PackageThisProject>True</PackageThisProject>
    </ProjectReference>
  </ItemGroup>
  <ItemGroup>
    <WixExtension Include="WixIIsExtension">
      <HintPath>$(WixExtDir)\WixIIsExtension.dll</HintPath>
      <Name>WixIIsExtension</Name>
    </WixExtension>
    <WixExtension Include="WixUtilExtension">
      <HintPath>$(WixExtDir)\WixUtilExtension.dll</HintPath>
      <Name>WixUtilExtension</Name>
    </WixExtension>
    <WixExtension Include="WixUIExtension">
      <HintPath>$(WixExtDir)\WixUIExtension.dll</HintPath>
      <Name>WixUIExtension</Name>
    </WixExtension>
    <WixExtension Include="WixNetFxExtension">
      <HintPath>$(WixExtDir)\WixNetFxExtension.dll</HintPath>
      <Name>WixNetFxExtension</Name>
    </WixExtension>
  </ItemGroup>
  <ItemGroup>
    <Content Include="ConfigurationInitialize.wxi" />
  </ItemGroup>
  <Import Project="$(WixTargetsPath)" />
  <PropertyGroup>
    <PreBuildEvent />
  </PropertyGroup>
  <Target Name="BeforeBuild">
    <MSBuild Projects="%(ProjectReference.FullPath)" Targets="Package" Properties="Configuration=$(Configuration);Platform=$(Platform)" Condition="'%(ProjectReference.PackageThisProject)'=='True'" />
    <PropertyGroup>
      <DefineConstants>BasePath=%(ProjectReference.RootDir)%(ProjectReference.Directory)obj\$(Platform)\$(Configuration)\Package\PackageTmp\</DefineConstants>
    </PropertyGroup>
    <HeatDirectory OutputFile="%(ProjectReference.Filename).wxs" 
                   Directory="%(ProjectReference.RootDir)%(ProjectReference.Directory)obj\$(Platform)\$(Configuration)\Package\PackageTmp"
                   DirectoryRefId="INSTALLFOLDER"
                   ComponentGroupName="%(ProjectReference.Filename)_Project"
                   SuppressCom="true"
                   SuppressFragments="true"
                   SuppressRegistry="true"
                   SuppressRootDirectory="true"
                   AutoGenerateGuids="false"
                   GenerateGuidsNow="true"
                   ToolPath="$(WixToolPath)" Condition="'%(ProjectReference.PackageThisProject)'=='True'"
                   PreprocessorVariable="var.BasePath" />
  </Target>
</Project>

【讨论】:

  • 我遇到了同样的问题,但到目前为止我还没有看到这是如何解决问题的。 DefineConstants 是否应该替换原来的 LinkerBaseInputPaths 元素?
  • @jpierson 我已经更新了答案,如果这不能回答你的问题,请告诉我。
  • 好的,多亏了你,我相信我现在一切正常。由于格式设置,我在 HeatDirectory 元素上缺少属性 PreprocessorVariable="var.BasePath"。接下来,我必须将其他 WIX 项目文件中的所有 SourceDir 引用替换为对 var.BasePath 的引用,包括在我的 XSLT 转换中。
  • 我要补充一点,我仍然不确定为什么 SourceDir 不再在 WIX 3.6 中工作,而在 WIX 3.5 中的教程之后它似乎可以正常工作。
  • 非常感谢艾伦!我已将信息放在我的博客上,我也会很快更改原始帖子。感谢您的帮助!
【解决方案2】:

当我从使用 Wix 建立基本网站转移到我们的生产网站之一时,我遇到了与您类似的问题。

假设您正在关注示例Paul Reynolds' example 和这个Paraesthesia's example

如果您查看下一页的 cmets - http://blogs.planetsoftware.com.au/paul/archive/2011/02/20/creating-a-web-application-installer-with-wix-3.5-and-visual.aspx

第一条评论提到更改 Paraesthesia 示例中的 beforebuild 方法。

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

我不得不删除转换属性并更改 DirectoryRefId,但到目前为止一切都很好。

希望能帮助您指明正确的方向。

【讨论】:

  • 感谢您的建议。当我有机会时,我会尝试这个并更新线程。
  • 虽然这不是我问题的解决方案,但它确实让我开始了一个新的方向。请查看标记的答案。
【解决方案3】:

更新:如果你把

<PropertyGroup>
<DefineConstants Condition="'%(ProjectReference.WebProject)'=='True'">
%(ProjectReference.Name).PackageDir=%(ProjectReference.RootDir)
%(ProjectReference.Directory)obj\$(Configuration)\Package\PackageTmp\
</DefineConstants>

并添加:

PreprocessorVariable="var.%(ProjectReference.Name).PackageDir"

See the comment towards the bottom。我不做转换,所以我把它省略了。 到 HeatDirectory 它应该可以工作,而不必将 proj 文件放在底部。

这可能会降低我的声誉,但我觉得有趣的是http://www.paraesthesia.com 网站,我曾经为一个项目工作,但在尝试另一个项目时却没有用。
在查看输出后,它似乎为 Heat 和 Candle 选择了正确的项目,但 Light 似乎随机选择了一个。在比较了这两个项目之后,我注意到工作项目的收获项目是最后列出的项目。当我将 .wixproj 文件中的项目移到最后一个引用时,它起作用了。
我此时使用的是 3.5.2519。我知道这是一个旧项目,但我们有一些项目需要 Harvest to True 并在 Visual Studio 中实际 Harvest。

【讨论】:

  • 不是相关的答案。
  • WIX 很难理解我认为我的回答确实回答了这个问题。
【解决方案4】:

所以你的 WcfService.wxs 包括:

<File Id="fil0118BBA61671E80581CA9C9AA6DD3E8D" KeyPath="yes" Source="SourceDir\Some.dll" />

这是指SourceDir\Some.dll。该文件必须存在于您编译项目的电脑上。您可能需要更改路径。

【讨论】:

  • 据我了解,SourceDir 是源 .dll 所在路径的关键字。 WcfService.wxs 实际上是收获的热目录的产物(WcfService.wxs 是自动创建的)。问题是如何解决它。我已经更新了我原来的帖子澄清。
  • @alan 如果您在构建期间每次都运行热,我认为您会在更新期间遇到问题,因为每次都会生成一个新的 guid。您可以将parameter -var 添加到 heat 以指定使用什么来代替 SourceDir。或者使用light的-b option来指定文件的存放位置。
  • 如果我通过 Visual Studio 2010 WIX 安装项目构建它,我应该把这个变量放在哪里?你知道任何例子吗?
  • @Wimmel 您可以创建一个 config.wxi 文件来存储您的变量,然后在您的安装项目中引用该文件。你可以在这里看到一些使用配置文件的例子:stackoverflow.com/questions/471424/wix-tricks-and-tips
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多