I have a Visual Studio 2015 Update 3 solution with 3 projects:
My top-level application is MyApp
which has a project reference on ClassLibrary2
which in turn has a project reference on ClassLibrary1
:
MyApp -> ClassLibrary2 -> ClassLibrary1
The ClassLibrary1
has a data file, data.bin
, that is required for its normal execution. It is expected that this data file will be found in a Resources/
sub-folder relative to where the ClassLibrary1
assembly is when the application is executed. The structure of the ClassLibrary1
is similar to:
ClassLibrary1.csproj
Resources/
data.bin
MyClassBehaviorDrivenByData.cs
...
The data.bin
file has its Build Action
property set to Content
(I have also tried with None
) and its Copy to Output Directory
set to Copy If Newer
.
If I do a full solution Rebuild, the data.bin
file finds its way to the output directory of MyApp
, as expected. However, if I do some changes in the MyApp
project and build the solution, the data.bin
file is deleted from the output directory of MyApp
(note: the Output window shows that only MyApp
is built since only the code of MyApp
was changed).
Workarounds:
I could use post-build steps in MyApp
to forcefully copy the data file to the output directory each time MyApp
builds. However, this goes against the principle that the developer "owning" ClassLibrary1
should not have to worry about modifying post-build scripts in consuming projects if he adds a new data file, modify existing ones or move them elsewhere.
I could directly add a reference to ClassLibrary1
from MyApp
. However, this violates the desire to hide away the ClassLibrary1
functionality/API under the ClassLibrary2
API (i.e., I don't want ClassLibrary1
API to leak into MyApp
).
My questions are: what causes the data.bin
file to be deleted from MyApp
's output directory during incremental builds of MyApp
and is there a way to prevent this to happen without using one of the 2 workarounds listed above?
The reason is that that file is deleted in Incremental Clean task, that is used to make sure the files are newest (but it just delete files for your scenario). To deal with this issue, you can add a new target to copy necessary files to the target folder.
For example(edit csproj file, add this code to the end (before ):
<ItemGroup>
<resourceFiles Include="..\ClassLibrary1\Resources\*.*"/>
</ItemGroup>
<Target Name="AfterBuild" DependsOnTargets="CopyFiles">
</Target>
<Target Name="CopyFiles" Inputs="@(resourceFiles)"
Outputs="@(resourceFiles->'bin\$(Configuration)\Resources\%(filename)%(extension)')">
<Message Text="after Copy files" Importance="high"/>
<Copy
SourceFiles="@(resourceFiles)"
DestinationFolder="bin\$(Configuration)\Resources"
/>
</Target>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With