Reputation: 34840
Given an MSBuild Task that runs in AfterTargets="AfterCompile"
and produces some files how do you get those files to be included in the current projects output so that the files will be copied to the bin directory of any projects referencing that project?
Upvotes: 2
Views: 1698
Reputation: 1076
Thank you, Kirill. That was an excellent answer and it helped me when trying to copy ETW manifest files from a different project's output. Below is the final output.
Since I've simply expanded upon Kirill's answer, I do not expect this answer to be accepted. I post this here in the hope it helps someone else.
<Target Name="IncludeEtwFilesInOutput"
BeforeTargets="GetCopyToOutputDirectoryItems">
<PropertyGroup>
<EtwManifestFile>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)$(OutDir)\My.etwManifest.man'))</EtwManifestFile>
<EtwResourceFile>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)$(OutDir)\My.etwManifest.dll'))</EtwResourceFile>
</PropertyGroup>
<ItemGroup>
<AllItemsFullPathWithTargetPath Include="$(EtwManifestFile)">
<TargetPath>My.etwManifest.man</TargetPath>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</AllItemsFullPathWithTargetPath>
<AllItemsFullPathWithTargetPath Include="$(EtwResourceFile)">
<TargetPath>My.etwManifest.dll</TargetPath>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</AllItemsFullPathWithTargetPath>
</ItemGroup>
</Target>
Upvotes: 1
Reputation: 8976
I have no guarantees that this is the right solution but it seems to work:
<Target Name="MyTarget" AfterTargets="AfterCompile">
<PropertyGroup>
<MyInput>D:\1.txt</MyInput>
<MyOutput>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)$(OutDir)\1.txt'))</MyOutput>
</PropertyGroup>
<Copy SourceFiles="$(MyInput)" DestinationFolder="$(OutDir)" SkipUnchangedFiles="true" />
<ItemGroup>
<AllItemsFullPathWithTargetPath Include="$(MyOutput)">
<TargetPath>1.txt</TargetPath>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</AllItemsFullPathWithTargetPath>
</ItemGroup>
</Target>
The relevant logic is here: http://sourceroslyn.io/#MSBuildTarget=GetCopyToOutputDirectoryItems http://sourceroslyn.io/#MSBuildItem=AllItemsFullPathWithTargetPath
Basically we rely on the fact that to determine the list of files to copy from dependent projects MSBuild calls the GetCopyToOutputDirectoryItems target of the dependent projects and uses its output (which is AllItemsFullPathWithTargetPath).
By adding ourselves to AllItemsFullPathWithTargetPath at the last minute we get picked up when a dependent project calls us.
Upvotes: 2