【问题标题】:MSBuild task paramer setup, multiple parametersMSBuild任务参数设置,多个参数
【发布时间】:2021-04-27 07:58:01
【问题描述】:

我按照几个月的教程设置了一个构建任务,它允许使用单个命名参数。

但是,我想升级任务以包含多个参数。我遇到了一些困难。

这是我当前的目标文件...

<Project>

    <PropertyGroup>
        <ThisAssembly>$(MSBuildThisFileDirectory)bin\Debug\netstandard2.0\ourapp.build.dll
        </ThisAssembly>    
        <FirstRun>false</FirstRun>    
        <FirstRun Condition="!Exists('$(ConstantGeneratorOutputFile)')">true</FirstRun>    
    </PropertyGroup>

    <UsingTask TaskName="ourapp.ConstantGeneratorTask"
               AssemblyFile="$(ThisAssembly)" />

    <!-- Pointing 'Outputs' to a non existing file will disable 
    up-to-date checks and run the task every time, there's probably a better way -->
    <Target Name="ourapp" 
            BeforeTargets="BeforeCompile;CoreCompile"
            Inputs="@(ConstantGeneratorSourceFiles)" 
            Outputs="$(ConstantGeneratorOutputFile).nocache">
        
        <ConstantGeneratorTask 
            SourceFiles="@(ConstantGeneratorSourceFiles)" 
            OutputFile="$(ConstantGeneratorOutputFile)"
            AppXamlFile="$(ConstantGeneratorAppXamlFile)"
            NameSpaceName="$(ConstantGeneratorNameSpaceName)"/>
        
        <ItemGroup Condition="Exists('$(ConstantGeneratorOutputFile)')">
            
            <FileWrites Include="$(ConstantGeneratorOutputFile)" />
            
            <Compile Include="$(ConstantGeneratorOutputFile)" 
                     Condition="$(FirstRun) == 'true'" />
            
        </ItemGroup>
    </Target>

</Project>

这是读取这些参数的代码...

namespace ourapp
{
    public class ConstantGeneratorTask : Task
    {
        [Required]
        public string OutputFile { get; set; } = "";

        [Required]
        public ITaskItem[] SourceFiles { get; set; } = Array.Empty<ITaskItem>();

        [Required]
        public string NameSpaceName { get; set; } = "";

        [Required]
        public string AppXamlFile { get; set; } = "";

这是 csproj 参数

    <ConstantGeneratorOutputFile>$(MSBuildThisFileDirectory)/Common/Constants.cs
    </ConstantGeneratorOutputFile>

    <ConstantGeneratorAppXamlFile>$(MSBuildThisFileDirectory)/App.xaml
    </ConstantGeneratorAppXamlFile>

    <ConstantGeneratorNameSpaceName>ourapp.Common
    </ConstantGeneratorNameSpaceName>

我想提供这样的东西..

<Items>
  <Item XamlFile="$(MSBuildThisFileDirectory)/App.xaml" 
      NS="ourapp.Common" 
      OutputFile="$(MSBuildThisFileDirectory)/Common/Constants.cs" />

  <Item XamlFile="$(MSBuildThisFileDirectory)/Resources/AutomationIds.xaml" 
      NS="ourapp.Resources" 
      OutputFile="$(MSBuildThisFileDirectory)/Common/AutomationIds.cs" />
</Items>

谁能指出我正确的方向?

【问题讨论】:

  • 您想从当前状态更改什么?您在定义或传递ConstantGeneratorSourceFiles 项目(例如&lt;ItemGroup&gt;&lt;ConstantGeneratorSourceFiles Include="**/*.foobar"/&gt;&lt;/ItemGoup&gt;)时遇到问题吗?
  • 我不确定如何在 csproj 中对项目进行分组以及如何读取目标文件。

标签: c# visual-studio msbuild


【解决方案1】:

您可以使用&lt;ItemGroup&gt; 将您的项目分组到 csproj 文件中,例如:

   <ItemGroup>
    <Xaml Include = "$(MSBuildThisFileDirectory)/App.xaml" >
      <NS>ourapp.Common</NS>
      <OutputFile>$(MSBuildThisFileDirectory)Common\Constants.cs</OutputFile>
    </Xaml>
  </ItemGroup>

然后,您可以在目标文件中使用%(Xaml.OutputFile),例如:

<Project>
  <Target Name="message" AfterTargets="build">
    <Message Text="%(Xaml.OutputFile)"/>
  </Target>
</Project>

更新: cs文件:

public class Common : Task
{
    [Required]
    public ITaskItem[] SourceFiles
    {
        get
        {
            return sourceFiles;
        }
        set
        {
            sourceFiles = value;
        }
    }

    [Required]
    public string NS { get; set;}

    [Output]
    public ITaskItem[] temp { get; }

    private ITaskItem[] sourceFiles;

    public override bool Execute()
    {
        foreach (var item in SourceFiles)
        {
            Console.WriteLine(item.ToString());
        }

        Console.WriteLine(NS);
        Console.WriteLine("*************Common****************");
        return true;
    }
}

目标文件:

  <UsingTask TaskName="Common" AssemblyFile="C:\ClassLibrary1.dll" />
  
  <Target Name="taskdll" AfterTargets="build">
    
    <ItemGroup>
      <XamlFile Include ="$(MSBuildThisFileDirectory)/App.xaml">
        <NS>ourapp.common</NS>
        <OutputFile>$(MSBuildThisFileDirectory)/Common/Constants.cs</OutputFile>
      </XamlFile>

      <XamlFile Include ="$(MSBuildThisFileDirectory)/App.xaml">
        <NS>ourapp.Resources</NS>
        <OutputFile>$(MSBuildThisFileDirectory)/Common/Constants.cs</OutputFile>
      </XamlFile> 
      
    </ItemGroup>
    
    <Message Text="***************START************"/>
    <Common SourceFiles ="@(XamlFile);%(XamlFile.NS);%(XamlFile.OutputFile)"
        NS ="%(XamlFile.NS)" 
        Condition ="'%(XamlFile.NS)' == 'ourapp.common'"/>
    <Message Text="***************END*************"/>
  </Target>

我这边的结果:

【讨论】:

  • @Jules,我已经更新了我的答案,希望它对你有用。
  • 这是你需要的pass data to an ITaskItem property of an MSBuild task吗?如果没有,我认为举个例子会更好。
  • 啊,是的,这很有帮助stackoverflow.com/a/678427/450456 虽然我希望有一个 itemgroup 示例,但是另一个答案是它们带有 Include 属性,是否会将它们视为实际文件。或者我可以包含字符串吗?
  • 是的,你可以包含字符串,它也可以工作。
  • 您介意更新您的答案吗,您可以添加两个项目组,显示两个不同的 NS 并添加 cs 吗?只是为了完整性。
猜你喜欢
  • 2020-05-25
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 2018-06-06
  • 2021-06-01
  • 1970-01-01
  • 2021-12-05
  • 2011-05-04
相关资源
最近更新 更多