0

我最近正在学习如何使用 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 文件,其中包含传递给我的 Copy_To_Build 任务的 SourceFiles 属性的项目。一切都很好。除了一件事:问题是我的自定义任务上的 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

总而言之:为什么我的任务被多次调用?

谢谢

4

1 回答 1

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

每个“目的地”元数据的唯一值都会调用一次。这称为“批处理”。您可以按照现在的工作方式执行此操作,或者将 DestinationFolder 属性设为可选,如果未指定,则任务可以在项目“SourceFiles”中查找“Destination”元数据并将项目复制到那个文件夹。

但是通常的做法是像现在这样,只需将 DestinationFolder 设为一个字符串。

于 2011-12-19T13:37:26.230 回答