1

I have a custom task written in C#. This custom task has an argument defined like this:

public required string[] StringArray { get; set; }

Then in a .csproj file I have these definitions:

<ItemGroup>
    <StringElemements Include="A" />
    <StringElemements Include="B" />
    <StringElemements Include="C" />
</ItemGroup>

<Target Name="MyTarget">
    <MyCustomTask StringArray="@(StringElements)" />
</Target>

Now when the task executes, I expected to have the values 'A', 'B', and 'C' in the property StringArray and that the task is being run once. However, when building the project, the task is being called for every element in the item group and then just pass a single element to the property. So in this example, the task is being executed three times while passing the values 'A', 'B', and 'C' separately to each task invocation.

I have been trying with transformations to get it right. If I call the task like this:

<Target Name="MyTarget">
    <MyCustomTask StringArray="A;B;C" />
</Target>

then all three elements are passed to the StringArray property of my custom task, which is what I want. Is there any way to achieve this? I need to have the StringElements in an item group like they are now, since they are needed in that form elsewhere in the build process.

2
  • The name of the property of the custom task is StringArray (see first code snippet). Changing the type (string[]) to List<string> or Collection<string> is not supported by msbuild. Commented 13 hours ago
  • An ItemGroup is passed to a task as an ITaskItem[], not a string[]. Commented 11 hours ago

1 Answer 1

1

Within the MSBuild documentation read "Write tasks for MSBuild" and "Tutorial: Create a custom task for code generation".

Change the C# code for your custom task to the following:

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

The Required attribute is from the Microsoft.Build.Framework namespace and is different from the required keyword.

An item collection is passed to a task as an ITaskItem[], not a string[]. Members of an item collection have metadata and the ITaskItem interface includes properties and methods for the metadata. The ItemSpec property of the ITaskItem will be the string from the Include.

Alternatively you could define StringArray as a string. @(StringElements) will be passed as the string value A;B;C. This is a conversion of the item collection to a property value. The semi-colon (;) is the default delimiter. Within your task, Split() on the ; to produce a string[].

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.