Внедрить EmbeddedResource, созданный задачей MSBuild - PullRequest
0 голосов
/ 26 апреля 2018

У меня есть пользовательская задача 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)));
            }
        }
    }
}

В моем файле целей у меня есть цель, определенная следующим образом:

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

В итоге я сталкиваюсь с двумя проблемами, которые могуКажется, проблема не решена:

  1. Хотя файлы создаются до задачи компиляции, они не включаются в сборку, если я не перекомпилирую проект без очистки выходных данных.При последующей сборке файл внедряется.
  2. Если я создаю файлы в IntermediateOutputPath, идентификатор встроенного ресурса включает этот путь.Поэтому вместо MyProject.SomeResource.txt я получаю MyProject.obj.netstandard2._0.SomeResource.txt

Примечание: - Если я заменю Path.Combine и просто сгенерирую выходной файл в проекте, это исправит проблему с идентификатором ресурса, ноне первая проблема, когда он не был встроен в первую компиляцию.

Как я могу убедиться, что мои сгенерированные файлы встроены в первую компиляцию, и что я могу сгенерировать их в IntermediateOutputPath, а не в каталоге Project с идентификатором ресурса, как если бы он был в проекте.

Ответы [ 2 ]

0 голосов
/ 24 января 2019

Вторую проблему можно решить, просто установив метаданные LogicalName для созданного элемента задачи.

TaskItem taskItem = new TaskItem(ProjectCollection.Escape(outputFile));   
taskItem.SetMetadata("LogicalName", $"{AssemblyName}.{item}.txt");
_generatedFiles.Add(taskItem);

Теперь, чтобы получить доступ к имени сборки внутри вашей задачи, просто добавьте AssemblyName свойство строки в MyTask иAssemblyName="$(AssemblyName)" к вашим целям.Это должно дать желаемый результат.

0 голосов
/ 31 мая 2018

Вам нужно запустить вашу цель раньше в процессе.CoreCompile слишком поздно.

Вы можете добавить следующее к вашему .csproj файлу.Эта цель будет выполняться до ResolveReferences и добавит Image.png в качестве встроенного ресурса.

<Target Name="IncludeDynamicResources" BeforeTargets="ResolveReferences">
    <ItemGroup>
      <EmbeddedResource Include="Image.png">
        <Type>Non-Resx</Type>
      </EmbeddedResource>
    </ItemGroup>
</Target>
...