У меня есть проект A (.NET Core), на который ссылается проект B. В проекте A у меня есть файл JSON, который необходимо обновить во время компиляции (чтобы заменить некоторые значения), и мне нужен файл JSON в построить выходные данные проекта B, которые также будут заменены.
Sln :
Project A
file.json (build action : none, copy always)
Project B
References
Project A
Содержимое файла A перед сборкой выглядит примерно так:
{
key : {{this will be replaced during build}}
}
После сборки это что-то вроде:
{
key : "VALUE"
}
До сих пор я пробовал использовать события после сборки в проекте A, и это хорошо работает для папки bin проекта A, но в папке bin проекта B у меня есть файл file.json до замены строки.
Я попытался отключить ускоренную сборку, так как думал, что это может быть проблемой, но, похоже, это не изменило результат.
Я также попробовал выполнить задачу msbuild:
<UsingTask TaskName = "TestReplace" TaskFactory = "CodeTaskFactory" AssemblyFile = "$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
<ParameterGroup />
<Task>
<Reference Include = "System.Xml" />
<Using Namespace = "System" />
<Using Namespace = "System.IO" />
<Code Type = "Fragment" Language = "cs">
<![CDATA[
var path = "file.json";
var fileContent = File.ReadAllText(path);
fileContent = fileContent.Replace("{{this will be replaced during build}}", "VALUE");
File.WriteAllText(path, fileContent);
]]>
</Code>
</Task>
</UsingTask>
<Target Name = "TestReplace" AfterTargets = "CopyFilesToOutputDirectory">
<TestReplace />
</Target>
Но с тем же результатом (JSON в порядке в выходной папке для проекта A, но не для проекта B)
Это задуманное поведение или я что-то неправильно настроил? И если это действительно предполагаемое поведение, какой рекомендуемый способ добиться замены строки как в проекте A, так и во всех проектах, которые от него зависят?
Я изучил генераторы одиночных файлов, но это звучит как сложное решение, и я бы предпочел избежать установки специального расширения на все компьютеры разработчиков.
Спасибо !
редактировать: кому интересно, в итоге я сделал что-то вроде этого:
<None Update = "file.json">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</None>
<None Update = "tmp\file.json" Link = "file.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<Target Name = "PreBuild" BeforeTargets = "PreBuildEvent">
<Exec Command = "do something that write from file.json to tmp/file.json" />
</Target>
и я добавил tmp/ в .gitignore
Это то, что я делаю сейчас, но это не работает для зависимых проектов.
В приведенном вами примере кода: Задача TestReplace имеет жестко закодированный путь "file.json". Этот путь будет интерпретироваться как относительный к каталогу проекта. Задача TestReplace запускается в цели TestReplace, которая запускается после цели CopyFilesToOutputDirectory. Итак, исходный файл копируется в выходной каталог, а затем преобразуется исходный файл в каталоге проекта. Проекты, ссылающиеся на проект A, будут копироваться из выходного каталога.
Ммм, моя вина, я слишком сильно упростил свой код перед публикацией, но путь к файлу file.json на самом деле является путем в выходной папке.

Проблема в том, что проект B на самом деле не копирует файлы из выходной папки проекта A.
Во время выполнения цели GetCopyToOutputDirectoryItems проекта B json извлекается непосредственно из A и добавляется в список _TransitiveItemsToCopyToOutputDirectory B (который позже выгружается в выходные данные B).
Вместо этого вы можете убедиться, что файл, добавленный в список <None> А, уже преобразован, а не исходный файл. Итак, подключите цель ранее к процессу сборки, выполните преобразование, а затем добавьте преобразованный файл в None.
Итак, вы предлагаете что-то вроде задачи перед сборкой, где я создаю новый файл «filereplaced.json», который, вероятно, находится в git ignore, и мне следует игнорировать file.json впоследствии во время сборки, чтобы использовать только filereplaced ? Я посмотрю и вернусь, спасибо.
Что-то вроде того. Добавьте задачу раньше, затем в пределах своей цели добавьте вновь созданный файл в <None> достаточно рано, чтобы он был подхвачен остальной частью процесса сборки.
<Target ...> <TestReplace /> <ItemGroup> <None ... /> </ItemGroup> </Target>Я принял ваш ответ, потому что выполнение задач по вариабилизации перед сборкой действительно работает, но я не уверен, что в конечном итоге сделаю это, хотя это кажется неправильным.
Преобразуйте копию файла file.json, находящуюся в выходном каталоге, а не исходный файл в каталоге проекта. (Или, другими словами, сборка не должна вносить изменения в исходные файлы с контролем версий.)