无法访问 MSBuild 中的 ArtifactStagingDirectory 变量

Can't access ArtifactStagingDirectory variable in MSBuild

在构建过程中,我试图将文件夹复制到工件文件夹 (\myserver\d$\TFBuild-Agent01\a)。

所以我把它放在 .csproj 文件中:

<Target Name="BeforeBuild">
  <Exec 
    Command="xcopy.exe  Databases &quot;$(Build.ArtifactStagingDirectory)\Databases&quot; /i /e /y /d" />
</Target>

这让我很感动

Error MSB4184: The expression """.ArtifactStagingDirectory" cannot be evaluated. Method 'System.String.ArtifactStagingDirectory' not found*

我在网上可以找到的所有内容都说 $(Build.ArtifactStagingDirectory) 是实现它的方法。但是没用。

在 TFS 2015 上使用 Visual Studio 2015 构建

这也不行:

<Exec 
Command="xcopy.exe  Databases &quot;$($Env:BUILD_ARTIFACTSTAGINGDIRECTORY)\Databases&quot; /i /e /y /d" />

The expression "$Env:BUILD_ARTIFACTSTAGINGDIRECTORY" cannot be evaluated.*

这没有错误,但看起来 %BUILD_ARTIFACTSTAGINGDIRECTORY% 被替换为空字符串:

 <Exec Command="xcopy.exe  Databases &quot;%BUILD_ARTIFACTSTAGINGDIRECTORY%\Databases&quot; /i /e /y /d" /> 

好的,我猜是因为我正在使用 Visual Studio 来构建我的解决方案,所以我无法从 .csproj 访问 $(Build.StagingDirectory)。但是,它作为 属性:

在命令行上传递到 "Visual Studio Build" 构建步骤
/p:OutDir="$(Build.StagingDirectory)"

这样就可以访问

<Exec Command="xcopy.exe  Databases &quot;$(OutDir)\Databases&quot; /i /e /y /d" />

您一直在混合使用代理允许您访问构建变量的方法。使用 $(some.variable) 的语法由代理本身解释。 MSBuild 具有类似的语法 - $(PropertyName) - 它做了一些不同的事情 - 它允许访问 msbuild 属性并且不允许在其名称中使用点 (.),因为你可以使用点来调用函数关于值(例如 $(OutputPath.Substring(3)))。

当你想从 MSBuild 引用构建变量时,你需要引用代理设置的环境变量。这是可能的,因为 MSBuild 使用其 属性 语法使所有环境变量都可以作为全局属性进行访问。 Build.ArtifactStagingDirectory 的环境变量是 BUILD_ARTIFACTSTAGINGDIRECTORY 因此您可以在 MSBuild 中使用 $(BUILD_ARTIFACTSTAGINGDIRECTORY).

我在 this script 中成功地使用它来默认 属性 当 运行 作为 TFS/VSTS 构建的一部分(PublishBaseDir 是自定义属性以后用到):

<PropertyGroup>
  <!-- Default artifact staging directory when built via VSTS / TFS agent -->
  <PublishBaseDir Condition="'$(PublishBaseDir)' == '' and '$(BUILD_ARTIFACTSTAGINGDIRECTORY)' != '' ">$(BUILD_ARTIFACTSTAGINGDIRECTORY)</PublishBaseDir>

  <!-- If not built on a known agent, use a "publish" subdir next to this file -->
  <PublishBaseDir Condition="'$(PublishBaseDir)' == ''">$(MSBuildThisFileDirectory)publish\</PublishBaseDir>

  <!-- Normalize directory if set manually or through ENV var -->
  <PublishBaseDir Condition="!HasTrailingSlash('$(PublishBaseDir)')">$(PublishBaseDir)\</PublishBaseDir>
</PropertyGroup>