c# - 将数组传递给自定义 MSBuild 任务

标签 c# msbuild msbuild-task

我以为这会很简单,但后来意识到我无法在任何地方找到任何关于它的信息。

我有一个这样的自定义任务:

public class MyCustomTask : Task
{
    [Required]
    public string[] SomeStrings {get;set;}

    public override bool Execute()
    {
        // Do something with strings...
    }
}

匹配的MSBuild东西基本是这样的:

<UsingTask TaskName="MyCustomTask" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildBinPath)\Microsoft.Build.Tasks.v4.0.dll">
    <ParameterGroup>
      <SomeStrings ParameterType="System.String[]" Required="true" />
    </ParameterGroup>
    <Task>
    ... 
    </Task>
</UsingTask>

<Target Name="DoSomething">
    <MyCustomTask SomeStrings="????" />
</Target>

不知道要在 SomeStrings 参数中放入什么,我想如果我输入“xxx,xxx,xxx”它可能会理解,所以任何人都可以对此有所了解。基本场景很像标记化,所以我需要一个字符串列表,然后是一些比较字符串,所以我需要传入 2 个列表/数组,但只是被难住了。

最佳答案

@BrianKretzler 非常喜欢使用 ITaskItem,因为它是 MSBuild 在您声明 <ItemGroup> 时使用的东西.

我只是想用一个完整的工作示例来说明答案,因为我在尝试完成同样的事情时发现了这篇文章,它帮助了我。 (很难搜索这些问题,因为关键字在不同的上下文中使用,所以希望这会帮助其他人)。

<UsingTask TaskName="MyCustomTask" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
    <ParameterGroup>
        <SomeStrings ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
    </ParameterGroup>
    <Task>
        <Code Type="Class" Language="cs"><![CDATA[
            using System;
            using Microsoft.Build.Framework;
            using Microsoft.Build.Utilities;

            public class MyCustomTask : Task
            {  
                public ITaskItem[] SomeStrings { get; set; }

                public override bool Execute()
                {
                    foreach (var item in SomeStrings)
                    {
                        Log.LogMessage(MessageImportance.High, 
                                       "Got item {0}",
                                       item.ItemSpec);
                        Log.LogMessage(" -> {0} -> {1}", 
                                       item.GetMetadata("Comparison"),
                                       item.GetMetadata("MoreDetail"));
                    }
                    return true;
                }
            }
        ]]></Code>
    </Task>
</UsingTask>

现在您可以调用此任务:

<Target Name="DoSomething">
    <ItemGroup>
       <SomeStrings Include="first string">
          <Comparison>first</Comparison>
       </SomeStrings>
       <SomeStrings Include="second string">
          <Comparison>2nd</Comparison>
          <MoreDetail>this is optional</MoreDetail>
       </SomeStrings>
    </ItemGroup>
    <MyCustomTask SomeStrings="@(SomeStrings)" />
</Target>

输出是:

Microsoft (R) Build Engine Version 4.0.30319.1
[Microsoft .NET Framework, Version 4.0.30319.269]
Copyright (C) Microsoft Corporation 2007. All rights reserved.

Build started 2012-10-19 5:41:22 PM.
Got first string
 -> first -> 
Got second string
 -> 2nd -> this is optional

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:00.12

当然你也可以使用像<ItemGroup><SomeStrings Include="**\*.txt" /></ItemGroup>这样的东西你会得到匹配的文件名列表,当然你可以使用 GetMetadata()访问 well-known file metadata

关于c# - 将数组传递给自定义 MSBuild 任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7820802/

相关文章:

c# - 网络 - 通过端口发送的字节数

msbuild - 如何防止 NuGet 在还原包时询问覆盖文件?

asp.net - 在 MSBuild 期间运行 powershell 脚本

msbuild - 使用 MSBuild 构建所有输出并将其复制到公共(public)文件夹时出现问题

.net - 在发布构建期间将依赖项移至另一个文件夹

visual-studio - MSBuild:在 Visual Studio 中构建解决方案后运行目标

c# - 如何在asp.net html页面中给出id并访问 anchor 标记?

C#-位图到字节数组

c# - 如何仅从时间跨度中获取小时数

visual-studio - SDK风格的csproj项目中的 "none include"和 "none update"有什么区别?