Пользовательская задача вызывается более одного раза - PullRequest
0 голосов
/ 19 декабря 2011

Недавно я изучаю, как использовать MSBuild, поэтому я решил заняться написанием своей собственной задачи MSBuild. Я обнаружил, что MSBuild прекрасно выполняет мою задачу ... но она вызывает ее снова и снова. Он повторяет вызов к нему много раз, хотя проект msbuild вызывает его только один раз.

Вот мой проект XML:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0"
        xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >

<PropertyGroup>
<BuildDir>build directory specified here</BuildDir>
.. various other stuff here too
</PropertyGroup>
<Import Project="file1.xml" />
<Import Project="file2.xml" />

<UsingTask TaskName="CopyToBuild.Copy_To_Build"
           AssemblyFile="CopyToBuild.dll" />

<Target Name="MyNewCopyTask">
    <Copy_To_Build  SourceFiles="@(copy_to_build)"
            DestinationFolder="%(Destination)"
            SkipUnchangedFiles="true"
            BuildDirectory="$(BuildDir)" />
</Target>

</Project>

Итак, как вы можете видеть, я вызываю мою задачу Copy_To_Build только один раз в проекте. Я импортирую XML-файл, содержащий элементы, которые передаются в атрибут SourceFiles моей задачи Copy_To_Build. Все отлично работает. За исключением одного: проблема в том, что мой метод Execute для моей пользовательской задачи вызывается более одного раза .

public class Copy_To_Build : Microsoft.Build.Utilities.Task
{
    [Required]
    public ITaskItem[] SourceFiles { get; set; }

    [Required]
    public ITaskItem[] DestinationFolder { get; set; }

    public String BuildDirectory { get; set; }

    public bool Clean { get; set; }

    public bool SkipUnchangedFiles { get; set; }

    public override bool Execute()
    {
        Console.WriteLine("Build Directory: {0}", BuildDirectory);
        ...
    }
}

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

Это вызывается более одного раза, потому что у меня установлен какой-то вариант потоков? Я вставил заявление, чтобы напечатать текущий поток:

Console.WriteLine("Current Thread: {0}", System.Threading.Thread.CurrentThread.ManagedThreadId);

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

@echo off

call "%VS100COMNTOOLS%..\..\VC\vcvarsall.bat" x64

rem set some build properties
set MISC=/nologo /verbosity:Normal
set LOGGING=/fileLogger /fileloggerparameters:LogFile=msbuild_foo.log;Encoding=UTF-8;Verbosity=Normal
set PROPERTY=/property:Platform=x64;Configuration=DebugUnicode;BuildDir=E:\foo
set TARGET=/target:MyNewCopyTask

msbuild %MISC% %LOGGING% %PROPERTY% %TARGET% foo.xml

pause

@echo on

Итак, подведем итог: почему моя задача вызывается более одного раза?

Спасибо

1 Ответ

1 голос
/ 19 декабря 2011
  <Copy_To_Build  SourceFiles="@(copy_to_build)"
        DestinationFolder="%(Destination)"
        SkipUnchangedFiles="true"
        BuildDirectory="$(BuildDir)" />

Он будет вызываться один раз для каждого уникального значения метаданных «Пункт назначения». Это называется «пакетирование». Вы можете сделать это так, как оно работает сейчас, или сделать свойство DestinationFolder необязательным, а если оно не указано, то задача может искать метаданные «Destination» в элементах «SourceFiles» и копировать элемент эта папка.

Но обычный способ сделать это, как у вас сейчас, просто сделать DestinationFolder строкой.

...