【问题标题】:Set Wix property to TFS build location将 Wix 属性设置为 TFS 构建位置
【发布时间】:2014-05-16 05:01:36
【问题描述】:

我一直在努力寻找问题的答案,但找不到;因此我将解决方案放在这里。我希望它对其他人有帮助。

问题:

我希望我的 Wix 项目在 TFS 2010 构建过程中构建。作为其中的一部分,我希望我的 Wix 的源文件位置指向 TFS 的构建位置。例如,我想要:

<File Id="ABC" KeyPath="yes" source="C:\Builds\1\MyBuild\assembly.dll" />

成为:

<File Id="ABC" KeyPath="yes" source="$(var.TFSLOCATION)\assembly.dll" />

“TFSLOCATION”是一个 wix 属性,需要填充 TFS 构建的位置。这需要在构建过程中进行,构建位置路径将传递给 Wix 项目。

解决方案:

我阅读了以下文章:

http://www.ageektrapped.com/blog/setting-properties-for-wix-in-msbuild/

这就是我对我的 Wix 项目文件 (wixproj) 所做的:

为了从 TFS MSBuild 进程中设置 wix 属性,wix 项目文件需要 两个 更改:

<PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <ProductVersion>3.5</ProductVersion>
    <SourceLocation Condition="'$(SourceLocation)' == '' ">UNKNOWN</SourceLocation>
    <ProjectGuid>{cae7e273-2de5-4a60-9c4f-9da5f094caf5}</ProjectGuid>
    <SchemaVersion>2.0</SchemaVersion>
    <OutputName>N4S.MSO.BAM.Installer</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>
    <SccProjectName>SAK</SccProjectName>
    <SccProvider>SAK</SccProvider>
    <SccAuxPath>SAK</SccAuxPath>
    <SccLocalPath>SAK</SccLocalPath>
  </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> 
  <OutputPath>bin\$(Configuration)\</OutputPath> 
  <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
  <DefineConstants>LOCATION=$(SourceLocation)</DefineConstants>
</PropertyGroup>

在上面的xml中,请注意以下两行:

<SourceLocation Condition="'$(SourceLocation)' == '' ">UNKNOWN</SourceLocation>

<DefineConstants>LOCATION=$(SourceLocation)</DefineConstants>

第一行指定一个属性“SourceLocation”并将其设置为默认的“UNKNOWN”值,如果是设置。第二行在“Release”配置中定义了一个名为“LOCATION”的常量。此常量的值设置为“SourceLocation”属性的值。

现在,您需要对您的 Product.wxs 文件(或任何您的 wxs 文件的名称)进行以下更改。

  • 首先定义一个 wix 属性。
<?define TFSLOCATION="$(var.LOCATION)"?>
  • 现在,更新 File 元素。
<File Id="ABC" KeyPath="yes" source="$(var.TFSLOCATION)\assembly.dll" />

TFS 2010 构建模板更改

  • 打开 TFS 2010 构建模板。
  • 查找任务“为项目运行 MSBuild”。
  • 打开此任务的属性并转到“CommandLineArguments”属性。
  • 将此属性的值设置为:
String.Format("/p:SourceLocation={0}", BinariesDirectory)

完成

您现在拥有一个从 TFS 构建过程中填充的 wix 属性。

【问题讨论】:

  • 在你的 Wix 脚本中使用相对路径不是更容易吗(例如 ..\..\..\SomeProject\bin\$(var.Configuration)\SomeAssembly.dll)?在那里,点符号让您回到源根目录,然后您将构建配置(调试/发布)作为 的一部分传递
  • 另外回答你自己的问题也很好,如果你没有得到其他答案,甚至建议你这样做,但你应该做的是将它分开,以便实际问题在问题部分中,然后创建一个答案那里有信息的问题。这样,人们就可以按预期分别对问题和答案的质量进行投票。
  • 关于拆分问题和答案的注意事项。
  • 我使用相对路径开始,但是,TFS 构建开始为某些文件提供“FileNotFound”错误。我试图解决该问题,但找不到 TFS 抱怨相对路径中可用的文件的合理原因。我也发布了一个关于此的问题,但没有得到任何有用的答案。使用这种方法解决了我的问题。
  • 我同意这一点,即使在 WiX 3.8 中,这似乎仍然是一个无法解释的问题。我在相对路径的开头(以 ..\..\..\.. 开头)明确引用了 $(sys.CURRENTDIR),以确保我可以通过阅读来确认指定了正确的位置输出消息的文本。然后我复制了据称丢失的文件的文本并将其粘贴到目标机器上的资源管理器中,实际上它确实存在。所以我将尝试这个解决方案,这样我就不需要使用相对路径。感谢您的建议...

标签: tfs wix tfsbuild


【解决方案1】:

如果您在 wixproj 文件中设置了对您正在构建的项目的引用,则可以引用它们的目标路径。因此,如果您有两个项目 MyProject 和 MyProjectInstaller,请在 MyProjectInstaller 中设置对 MyProject 的引用。

现在在 product.wxs 文件中,您的 File 元素将如下所示:

<File Id='EXE' Name='$(var.MyProject.TargetDir)\MyProject.exe' />
<File Id='DLL' Name='$(var.MyProject.TargetDir)\MyProject.dll' />
...

这样做的好处是,无论您是在本地构建还是在构建服务器上构建,目标目录都是正确的。

【讨论】:

    【解决方案2】:

    回答问题,即使答案在问题中,也不会显示没有答案。

    【讨论】:

      【解决方案3】:

      我最终使用了相同的方法,但做了一些重要的改进。

      1) 我将 TFS 构建过程模板中的 SourcesDirectory 和 BinariesDirectory 作为单独的属性传递给 MSBuild,以便我可以访问它们。

      2) 为了使生成的 MSBuild 属性可用于 MSBuild 项目中执行的每个任务,我将它们添加到 BeforeBuild 目标中的 $(CustomPropertiesForBuild)。

      3) 我没有将 DefineContants 元素添加到 PropertyGroup,而是将 CreateProperty 添加到 BeforeBuild 目标。

      2 和 3 之所以完成,是因为以下原因与在单个 TFS 构建中运行多个 Wix 项目解决方案有关。如果按照最初的建议定义常量,可能会发生两件事。

      首先,如果您在您的 WiX 项目中运行 heat.exe 作为具有多个 WiX 项目的构建的一部分,则可能会出现一个问题,即 DevEnv 保留进程句柄并且在每次运行时都不会重新定义常量,除非您清理输出文件夹并释放文件句柄。

      其次,如果由于某种原因您的 Wix 项目之一未构建(配置未指定构建它或指定的配置对该项目无效),则由于某种原因,MSBuild 属性将重置为 null 并且因此常量被重新定义为空,所以你失去了属性。另一方面,如果您通过覆盖 BeforeBuild 目标来定义属性,则一切正常。

      请注意,您必须覆盖 BeforeBuild 属性,而不是 BeforeEndToEndIteration 属性,才能正常工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-05-15
        • 2018-04-15
        • 1970-01-01
        • 1970-01-01
        • 2016-07-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多