在控制台应用程序的每个构建上执行自定义任务,而不在 csproj 中提及“UsingTask”或“Import”,使用 MSBuild 从类库

问题描述 投票:0回答:1

我正在开发 C# 控制台应用程序,我希望 每次构建控制台应用程序时自动执行自定义任务。我想使用 MSBuild 和类库来实现此目的,但我不确定如何正确设置它。

这就是我的想法:

在我的控制台应用程序的 csproj 文件中,我想在 中定义一个名为 的自定义元素。该元素应包含一些与自定义任务相关的信息:

<ItemGroup>
    <PackageReference Include="MyClassLib" Version="1.2.3"/>
    <MyInfo>
        <Name>XYZ</Name>
    </MyInfo>
</ItemGroup>

然后,我希望处理此 元素并执行自定义任务的所有必要逻辑都在名为“MyClassLib”的单独类库项目中处理。这应包括定义 MSBuild 任务和属性。

我已经阅读了有关自定义 MSBuild 任务和属性的信息,但我在实际实现方面遇到了困难。

这是我尝试过但没有成功的方法:

  1. 创建类库项目(MyClassLib):

    1.1。定义了一个GenerateXmlTask类:

namespace ClassLibrary1;

using System.Xml.Linq;
using Microsoft.Build.Framework;

public class GenerateXmlTask : Microsoft.Build.Utilities.Task
{
    [Required]
    public ITaskItem[]? MyInfo { get; set; }

    public override bool Execute()
    {
        //some logic

        File.WriteAllText("mydata.xml", xml.ToString()); // Write to file

        return true;
    }
}

1.2。定义了一个GenerateXmlTask.props:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <UsingTask TaskName="GenerateXmlTask" AssemblyFile="$(MSBuildThisFileDirectory)$(OutputPath)MyClassLib.dll"/>
</Project>

1.3。定义了一个GenerateXmlTask.targets:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Target Name="GenerateXmlTask " AfterTargets="Build">
        <GenerateXmlTask MyInfo="@(MyInfo)" />
    </Target>
</Project>

1.4。 MyClassLib.csproj 的 csproj:

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFramework>net6.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="Microsoft.Build.Framework" Version="17.7.2" />
        <PackageReference Include="Microsoft.Build.Utilities.Core" Version="17.7.2" />
    </ItemGroup>
    
    <ItemGroup>
        <Content Include="GenerateXmlTask.props">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
            <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
        </Content>
        <Content Include="GenerateXmlTask.targets">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
            <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
        </Content>
    </ItemGroup>

</Project>

然后控制台应用程序的 csproj 看起来如顶部所示。


我得到的错误是:

ConsoleApp1.csproj(21,9): error MSB4232: Items that are outside Target elements must have one of the following operations: Include, Update, or Remove

这是由于其 csproj 中的“MyInfo”标签所致。这个问题不仅仅是关于这个错误,我想知道我还缺少什么的概念答案。

提前感谢您的帮助!

c# .net .net-core msbuild msbuild-task
1个回答
0
投票

这个(来自 ConsoleApp1.csproj 文件,第 21 行,第 9 列):

<ItemGroup>
    <PackageReference Include="MyClassLib" Version="1.2.3"/>
    <MyInfo>
        <Name>XYZ</Name>
    </MyInfo>
</ItemGroup>

MSBuild 无效并导致报告错误 MSB4232。

不能“在内定义自定义元素......”。这是不允许的。

ItemGroup
可以包含多个不同项目集合的项目元素,例如:

<ItemGroup>
    <Foo Include="A;B" />
    <Bar Include="C;D" />
</ItemGroup>

MSB4232 错误是因为

<MyInfo>
是一个 item 元素,并且必须具有
Include
Update
Remove
属性。

您可以向项目添加自定义元数据,例如:

<ItemGroup>
    <PackageReference Include="MyClassLib" Version="1.2.3">
        <MyData>XYZ</MyData>
    </PackageReference>
</ItemGroup>

但我认为这没有帮助。

您似乎正在尝试在构建控制台应用程序时生成 XML 数据文件。您不需要为此自定义任务。

将以下目标添加到 ConsoleApp1.csproj:

<Target Name="GenerateXmlTask" BeforeTarget="BeforeBuild">
    <ItemGroup>
        <XmlData Include="&lt;MyInfo&gt;"/>
        <XmlData Include="    &lt;Name&gt;XYZ&lt;/Name&gt;"/>
        <XmlData Include="&lt;/MyInfo&gt;"/>
    </ItemGroup>
    <PropertyGroup>
        <XmlDataFileName>mydata.xml</XmlDataFileName>
    </PropertyGroup>
    <WriteLinesToFile File="$(XmlDataFileName)" Lines="@(XmlData)" />
    <ItemGroup>
        <Content Include="$(XmlDataFileName)">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
            <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
        </Content>
    </ItemGroup>
</Target>
© www.soinside.com 2019 - 2024. All rights reserved.