In my .csproj file I've added the following config:
<ItemGroup>
<None Include="$(USERPROFILE)\.nuget\packages\microsoft.data.sqlclient.sni\1.0.19235.1\buildTransitive\net46\x64\SNI.dll">
<!-- This is a workaround to include SNI.dll in the NuGet package resulting from the pipeline in Azure DevOps. -->
<Link>x64\SNI.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
But, it's been difficult to find documentation on how PreserveNewest
actually works. I've looked at various Stackoverflow posts, and found this page from the documentation, which states under the section for the None
element:
CopyToOutputDirectory Optional string. Determines whether to copy the file to the output directory. Values are:
- Never
- Always
- PreserveNewest
It's doesn't really describe how it works. Does anyone know this? By what criteria does it decide what is newest? File changed date? Other version metadata? What does it mean by "preserve"?
The aim of the config is to copy the SNI.dll
file to the bin/x64
directory, which it does successfully.
It is based on file modification timestamps. Even looking at the responsible source code is a bit obscure since MSBuild uses Inputs/Outputs of targets to determine if a part of the build logic needs to be executed.
So if you modify the source file on disk, the next MSBuild run will compare the timestamp to the timestamp of the expected file in the output directory and will only execute that logic if the destination file is missing or has the same or a newer modification date.
This means that it is preferably to select PreserveNewest
if you don't expect the file to change in the target directory (e.g. database file that is modified when the app is started) over Always
for two reasons:
Always
- which means a "Build"/"Run" in VS will always invoke MSBuild and not skip a project if it knows that no files have changed.