Вот решение на основе msbuild, которое на самом деле довольно простое и не навязчивое.Создайте файл CopySource.targets в каталоге решения, например, содержимое:
<Project>
<Target Name="CopySourcesUsed" AfterTargets="AfterCompile">
<PropertyGroup>
<DestinationDirectory>c:\temp\dest\</DestinationDirectory>
<SourceDirectory>$([System.IO.Path]::GetDirectoryName($(MSBuildProjectDirectory)))</SourceDirectory>
</PropertyGroup>
<ItemGroup>
<CompileSources Condition="!$([System.Text.RegularExpressions.Regex]::IsMatch('%(Identity)', `.*Assembly(Attributes|Info)\.cs`))" Include="@(Compile)"/>
<AllSources Include="@(CompileSources);@(EmbeddedResource);$(MSBuildProjectFile)" />
<AllSources>
<Dest>$([System.String]::new('%(FullPath)').Replace($(SourceDirectory), $(DestinationDirectory)))</Dest>
</AllSources>
</ItemGroup>
<Message Importance="High" Text="%(AllSources.FullPath) -> %(AllSources.Dest)"/>
<Copy SourceFiles="@(AllSources)" DestinationFiles="@(AllSources->'%(Dest)')" />
</Target>
</Project>
Затем запустите сборку наподобие
dotnet msbuild mysolution.sln /p:CustomAfterMicrosoftCSharpTargets=/path/to/CopySource.targets
(примечание dotnet build
также работает для меня, но может и не работатьв более старых версиях не знаю)
Это импортирует ListSources.Targets в каждый файл проекта и запускает цель CopySourcesUsed после компиляции.До компиляции где-то тоже будет работать, но тогда вам нужно точно выяснить, когда: после компиляции все элементы определенно собраны.Например, элемент AllSources заполнен исходными файлами компиляции и встроенными ресурсами.Как видите, элемент Compile фильтруется, чтобы исключить сгенерированные файлы AssemblyAttributes / AssemblyInfo, так как вы, вероятно, не хотите их.Альтернативой может быть запуск этой цели до добавления этих файлов, но опять же: это просто сложнее.Могут быть и другие вещи, которые вы хотите скопировать (xaml / config / ...), и в этом случае вам нужно выяснить имя элемента, который нужно включить.Сначала проверьте, не указан ли он просто в csproj.Если запустить сборку с подробным диагностическим описанием, можно указать имя: dotnet msbuild mysolution.sln /v:diag
.
Вместо внедрения этой логики в командную строку вы можете вместо этого импортировать файл в каждый ваш проект или использовать другую точку расширения, например, сделатьдля всей системы, поместив его в какой-то каталог ImportAfter, все эти решения можно найти здесь, на SO, вероятно.