2009-09-10 4 views
1

Я пытаюсь сделать задачу в моих сборках TFS более общей, и одна из вещей, которую я пытаюсь сделать, - скопировать некоторые файлы в разные каталоги в зависимости от сборки, используя эту задачу. Я играл с идеей использования свойств, но я не мог придумать, как это сделать, поэтому я попытался использовать метаданные элементов, поскольку я смог сделать это в другом месте в одном и том же файле цели Я работаю, только на этот раз, я бы хотел использовать свойства.Настройка метаданных элемента с использованием свойства

Вот что я хочу сделать:

<ItemGroup> 
    <DestinationParent Include="$(DeploymentPath)"> 
    <DestinationParentPath>$(DeploymentPath)</QuartzParentPath> 
    </DestinationParent> 
</ItemGroup> 

И позже в сборке, я пытался скопировать некоторые файлы в папку назначения с помощью ссылки на метаданные элемента:

<Copy SourceFiles="@(FilesToCopy)" DestinationFiles="@(FilesToCopy-&gt;'%(DestinationParentPath)\Destination\%(RecursiveDir)%(Filename)%(Extension)')" ContinueOnError="false" ></Copy> 

К сожалению, после того, как сборки сборки, мой BuildLog показывает следующее:

Copying file from "$(BinariesRoot)\%(ConfigurationToBuild.FlavorToBuild)\<File being copied>" to "\Destination\<File being copied>". 

% (DestinationParentPath) имеет по какой-либо причине расширена до пустой строки. Использование% (DestinationParent.DestinationParentPath) вызвало ошибку, сообщив мне, что я просто должен использовать% (DestinationParentPath). $ (DeploymentPath) расширяется до правильной строки, как и ожидалось в нескольких других местах сборки.

Другим источником путаницы является то, что с помощью% (ConfigurationToBuild.FlavorToBuild) давала правильное значение, то есть тест, как можно видеть в следующем:

EDIT: это определено в рамках проекта корневого узла, в то время как ItemGroup с DestinationParentPath определяется под узлом Target. Это также имеет значение?

<ItemGroup> 
    <ConfigurationToBuild Include="Test|Any CPU"> 
    <FlavorToBuild>Test</FlavorToBuild> 
    <PlatformToBuild>Any CPU</PlatformToBuild> 
    </ConfigurationToBuild> 
</ItemGroup> 

Это не похоже, как будто Включать атрибут имеет значение, когда вы заинтересованы только в строке в метаданных элемента, так как я уверен, что «Test | Любой процессор» не ссылается на какой-либо сам файл.

Так что еще раз, почему% (DestinationParentPath) расширяется до пустой строки?

EDIT: Я забыл упомянуть, что я также пытался жестко кодировать фактический путь для DestinationParentPath, но это все равно привело к тому, что% (DestinationParentPath) расширяется до пустой строки.

ответ

1

EDIT: это определено в корневом узле Project, тогда как ItemGroup с DestinationParentPath определяется под целевым узлом. Это также имеет значение?

Да, это имеет значение. Возможность определять ItemGroup внутри Target является новой для msbuild 3.5. Несмотря на то, что он выглядит декларативно, он фактически выполняется во время выполнения, как если бы вы назвали старые задачи CreateItem/CreateProperty. Это само по себе приводит к потенциальным проблемам: вам нужно учитывать, когда вызывающая задача (сначала) вызвана. Order of operations is not always obvious to the naked eye. Может быть разумным сделать задачу, в которой вы используете% (DestinationParentPath), в зависимости от задачи, где она создана, даже если нет «логической» зависимости.

Кроме того, существуют вековые подсчеты/ошибки ошибок msbuild. Dynamically created properties & items are not visible to "sibling" tasks. Также items updated in nested builds aren't always bubbled up.

Ознакомьтесь с обходными способами в ссылках, вы сможете найти что-то, что сработает для вас, даже если это нехорошо.

+0

Спасибо за ваши ответы и за ссылки ... выяснил, как решить мою проблему :) (и да, это немного нехорошо, но все же работает неплохо) Один вопрос, который меня все еще смущает: кажется, что% (Configuration.FlavorToBuild), о котором я упоминал выше, рассматривается как глобальный ... элемент? Поэтому я могу использовать его в других частях поля? –

+1

Элемент «Конфигурация» настроен Team Build очень рано, поэтому я не удивлен, что он работает на всех ваших скриптах без какой-либо дополнительной работы. ///// Возможно, «область» - это неправильное слово для использования. Свойства и элементы всегда «глобальны» в msbuild, в том смысле, что $ (foo) всегда ссылается на «тот же» $ (foo), независимо от того, где он появляется. C# analogy: представьте, что нет ключевого слова namespace и только 1 определение класса. Как правило, мы всегда передаем один экземпляр этого класса. Первая ссылка описывает управление потоком. Последние два описывают причуды, в которых устаревшая копия передается в/из. –