注入由MSBuild任务创建的EmbeddedResource

注入由MSBuild任务创建的EmbeddedResource,msbuild,msbuild-task,Msbuild,Msbuild Task,我有一个自定义MSBuild任务,该任务基于没有生成操作的文件生成文件。生成的文件需要嵌入到最终部件中。任务如下所示: public class MyTask : Task { public string OutputDirectory { get; set; } public string[] NoneIncluded { get; set; } private IEnumerable<ITaskItem> _generatedFiles; [O

我有一个自定义MSBuild任务,该任务基于没有生成操作的文件生成文件。生成的文件需要嵌入到最终部件中。任务如下所示:

public class MyTask : Task
{
    public string OutputDirectory { get; set; }

    public string[] NoneIncluded { get; set; }

    private IEnumerable<ITaskItem> _generatedFiles;
    [Output]
    public ITaskItem[] GeneratedFiles => _generatedFiles.ToArray();

    public override bool Execute()
    {
        _generatedCssFiles = new List<ITaskItem>();
        foreach(var item in NoneIncluded)
        {
            if(someCondition)
            {
                var contents = DoFoo(item);
                var outputPath = Path.Combine(OutputDirectory, $"{item}.txt");
                File.WriteAllText(outputPath, contents);
                _generatedFiles.Add(new TaskItem(ProjectCollection.Escape(outputFile)));
            }
        }
    }
}
公共类MyTask:Task
{
公共字符串输出目录{get;set;}
公共字符串[]{get;set;}
私有IEnumerable生成的文件;
[输出]
public ITaskItem[]GeneratedFiles=>_GeneratedFiles.ToArray();
公共重写bool Execute()
{
_generatedCssFiles=新列表();
foreach(不包括中的var项目)
{
如果(某些条件)
{
var内容=DoFoo(项目);
var outputPath=Path.Combine(OutputDirectory,$“{item}.txt”);
File.writealText(输出路径,内容);
_添加(新任务项(ProjectCollection.Escape(outputFile));
}
}
}
}
在我的目标文件中,我有一个如下定义的目标:

<PropertyGroup>
    <CoreCompileDependsOn>MyTarget;$(CoreCompileDependsOn);</CoreCompileDependsOn>
</PropertyGroup>

<Target Name="MyTarget"
        BeforeTargets="CoreCompile;Build">

  <MyTask OutputDirectory="$(IntermediateOutputPath)"
          NoneIncluded="@(None)">
    <Output ItemName="FilesWrite"
            TaskParameter="GeneratedFiles"/>
    <Output ItemName="EmbeddedResource" 
            TaskParameter="GeneratedFiles" />
  </MyTask>

</Target>

我的目标$(CoreDependson);
我最终遇到了两个似乎无法解决的问题:

  • 尽管文件是在编译任务之前生成的,但它不会嵌入到程序集中,除非我在不清理输出的情况下重建项目。在随后的构建中,该文件被嵌入
  • 如果我在
    中间输出路径
    中生成文件,则嵌入的资源id包括该路径。因此,我得到的不是
    MyProject.SomeResource.txt
    MyProject.obj.netstandard2.\u 0.SomeResource.txt
  • 注: -如果我替换
    路径.Combine
    并在项目中生成输出文件,它会修复资源id的问题,但不会修复第一个问题,因为它不会嵌入到第一次编译中


    如何确保我生成的文件嵌入到第一次编译中,并且我可以在IntermediateOutput路径中生成它们,而不是在项目目录中生成资源id,就像它在项目中一样。

    您需要在管道中更早地运行目标<代码>核心编译太晚了

    您可以将以下内容添加到
    .csproj
    文件中。此目标将在
    resolverences
    之前运行,并将
    Image.png
    添加为嵌入式资源

    <Target Name="IncludeDynamicResources" BeforeTargets="ResolveReferences">
        <ItemGroup>
          <EmbeddedResource Include="Image.png">
            <Type>Non-Resx</Type>
          </EmbeddedResource>
        </ItemGroup>
    </Target>
    
    
    非Resx
    
    只需将LogicalName元数据设置为创建的任务项,即可解决第二个问题

    TaskItem taskItem = new TaskItem(ProjectCollection.Escape(outputFile));   
    taskItem.SetMetadata("LogicalName", $"{AssemblyName}.{item}.txt");
    _generatedFiles.Add(taskItem);
    
    现在要访问任务中的程序集名称,只需将
    AssemblyName
    string属性添加到
    MyTask
    AssemblyName=“$(AssemblyName)”
    到目标中即可。这将产生预期的结果