I have a class library that has several files that it depends on, and those files must be packaged up for deployment with any project that depends on this library. Right now this means that I must customize each one of those dependent projects to ensure that they copy the files, in addition to adding the library as an MSBuild PrjectReference. When more files are added, all of the projects must be updated.
I've been looking through Microsoft.Common.targets for a way to include these files with the outputs of the library's own project file, so any project that has a ProjectReference to the library will automatically get the files when doing a build. I haven't gotten anything working yet, but I'm curious more generally if this is possible. It seems like it should be, and the _CopyFilesMarkedCopyLocal target even respects an otherwise-unused %(DestinationSubDirectory) metadata item that would allow for customized placement of those files, which would be perfect.
I believe what I'm missing is, for building a project A that depends on project B, the piece that adds the project outputs of project B into the items for project A's build.
EDIT: Leo's comment, I hadn't noticed that files marked with CopyToOutputDirectory are also copied to dependent project output directories because we use ItemGroups with names other than Content, EmbeddedResource, None, etc. Digging deeper, the target that uses those is GetCopyToOutputDirectoryItems and it appears to recursively call the MSBuild task to determine the project outputs, so I should be able to define some custom target that can be imported into our projects that adds our custom ItemGroups in the GetCopyToOutputDirectoryItems target, so that we don't have to use Content/None, etc.
However, the target that does the copying though is _CopyOutOfDateSourceItemsToOutputDirectoryAlways, which doesn't respect %(DestinationSubDirectory) unfortunately, and so all of these files are copied directly to $(OutDir).
My new goal is to see if there's some way to add custom files into the ReferenceCopyLocalPaths ItemGroup of dependent projects so that they are copied instead by the _CopyFilesMarkedCopyLocal target, which does utilize %(DestinationSubDirectory).
The above title should be closer to bwerks's goal. As test we could to know that the custom build action for ItemGroups would not copied to the Output directory, so we need to our custom build action to the target
_CopyOutOfDateSourceItemsToOutputDirectoryAlways
.To accomplish this, open the file
Microsoft.Common.CurrentVersion.targets
in the MSBuild 15.0 folderC:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets
(Make sure you have sufficient permissions and back up it), find the target_CopyOutOfDateSourceItemsToOutputDirectoryAlways
:Then we could to know the copy source file is
@(_SourceItemsToCopyToOutputDirectoryAlways)
, search_SourceItemsToCopyToOutputDirectoryAlways
this in the targets, you will find:Could to know the source file is
@(ContentWithTargetPath)
, keeping search theContentWithTargetPath
in the target, finally we got following:So, we could to know how the target is to copy the default build action file to the output directory.
Now, go to our custom build action, we just need add our custom build action to the
ItemName="ContentWithTargetPath"
, so add following in the fileMicrosoft.Common.CurrentVersion.targets
:Save it.
For the file in the project file
.csproj
:Hope this helps.