Не удается получить доступ к переменной ArtifactStagingDirectory в MSBuild

В процессе сборки я пытаюсь скопировать папку в папку артефактов (\myserver\d$\TFBuild-Agent01\66\a).

Итак, я поместил это в файл .csproj:

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

это меня заводит

Ошибка MSB4184: выражение """.ArtifactStagingDirectory" не может быть оценено. Метод «System.String.ArtifactStagingDirectory» не найден*

Все, что я могу найти в Интернете, говорит, что $(Build.ArtifactStagingDirectory) - это способ сделать это. Но это не работает.

Создание с помощью Visual Studio 2015 на TFS 2015

Это тоже не работает:

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

Выражение "$Env:BUILD_ARTIFACTSTAGINGDIRECTORY" не может быть оценено.*

Это не ошибка, но похоже, что %BUILD_ARTIFACTSTAGINGDIRECTORY% заменяется пустой строкой:

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

person mhenry1384    schedule 07.07.2017    source источник


Ответы (2)


Вы смешивали способы доступа к переменным сборки, которые позволяет вам агент. Синтаксис с использованием $(some.variable) интерпретируется самим агентом. MSBuild имеет похожий синтаксис — $(PropertyName) — который делает что-то другое — он дает доступ к свойствам msbuild и не позволяет использовать точки (.) в своем имени, поскольку вы можете использовать точку для вызова функций для значения (например, $(OutputPath.Substring(3))).

Если вы хотите ссылаться на переменные сборки из MSBuild, вам нужно ссылаться на переменную среды, которую устанавливает агент. Это возможно, потому что MSBuild делает все переменные среды доступными как глобальные свойства, используя свой синтаксис свойств. Переменная среды для Build.ArtifactStagingDirectoryBUILD_ARTIFACTSTAGINGDIRECTORY, поэтому вы можете использовать ее в MSBuild с помощью $(BUILD_ARTIFACTSTAGINGDIRECTORY).

Я успешно использовал его в этом скрипте для свойства по умолчанию при запуске в составе сборки 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>
person Martin Ullrich    schedule 09.07.2017
comment
Искал везде подобный пример, спасибо!. В самих документах есть примеры в любом другом контексте и сценарии, КРОМЕ самого полезного!! - person Warren; 23.01.2020

Хорошо, я предполагаю, что, поскольку я использую Visual Studio для создания своего решения, я не могу получить доступ к $(Build.StagingDirectory) из .csproj. Однако он передается в командной строке на шаг сборки «Visual Studio Build» как свойство:

/p:OutDir="$(Build.StagingDirectory)"

Таким образом, к этому можно получить доступ, выполнив

<Exec Command="xcopy.exe  Databases &quot;$(OutDir)\Databases&quot; /i /e /y /d" />
person mhenry1384    schedule 07.07.2017
comment
Не уверен, что ваша проблема решена сейчас, но для отладки таких случаев полезна задача MSBuild Message: ‹Message Text=Build.ArtifactStagingDirectory=$(Build.ArtifactStagingDirectory) Importance=high/› Таким образом, вы увидите, какое значение оно имеет действительно был установлен внутри csproj - person ackh; 09.07.2017