Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inject EmbeddedResource created by MSBuild Task

I have a custom MSBuild Task that generates a file based on files that have no build action. The generated files need to be embedded into the final assembly. The task looks something like this:

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)));
            }
        }
    }
}

In my targets file, I then have a target defined like the following:

<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>

I ultimately end up with two issues that I can't seem to resolve:

  1. Although the files are generated prior to the compile task, it isn't embedded into the assembly, unless I rebuild the project without cleaning the outputs. On the subsequent build the file is embedded.
  2. If I generate the files in the IntermediateOutputPath, the embedded resource id includes that path. So instead of MyProject.SomeResource.txt I get MyProject.obj.netstandard2._0.SomeResource.txt

Note: - If I replace the Path.Combine and simply generate the output file in the project, it fixes the issue of the resource id, but not the first issue with it not being embedded on the first compile.

How can I ensure the my generated files are embedded on the first compilation, and that I can generate them in the IntermediateOutputPath rather than the Project directory with a resource id as if it were in the project.

like image 746
Dan Siegel Avatar asked Oct 16 '25 17:10

Dan Siegel


1 Answers

You need to run your target earlier in the pipeline. CoreCompile is too late.

You can add the following to your .csproj file. This target will run before ResolveReferences and add Image.png as an embedded resource.

<Target Name="IncludeDynamicResources" BeforeTargets="ResolveReferences">
    <ItemGroup>
      <EmbeddedResource Include="Image.png">
        <Type>Non-Resx</Type>
      </EmbeddedResource>
    </ItemGroup>
</Target>
like image 118
Michael Baker Avatar answered Oct 19 '25 08:10

Michael Baker



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!