I'm trying to create NuGet package for a .Net assembly which does pinvoke to a native win32 dll. I need to pack both the assembly and the native dll with the assembly added to the project references (no problem at this part) and the native dll should be copied into the project output directory or some other relative directory.
My questions are:
Using the Copy
target in the targets file to copy required libraries won't copy those files to other projects which reference the project, resulting in a DllNotFoundException
. This can be done with a much simpler targets file though, using a None
element, as MSBuild will copy all None
files to referencing projects.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<NativeLibs Include="$(MSBuildThisFileDirectory)**\*.dll" />
<None Include="@(NativeLibs)">
<Link>%(RecursiveDir)%(FileName)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
Add the targets file to the build
directory of the nuget package along with the required native libraries. The targets file will include all dll
files in all child directories of the build
directory. So to add an x86
and x64
version of a native library used by an Any CPU
managed assembly you would end up with a directory structure similar to the following:
The same x86
and x64
directories will be created in the project's output directory when built. If you don't need subdirectories then the **
and the %(RecursiveDir)
can be removed and instead include the required files in the build
directory directly. Other required content files can also be added in the same way.
The files added as None
in the targets file won't be shown in the project when open in Visual Studio. If you are wondering why I don't use the Content
folder in the nupkg it's because there's no way to set the CopyToOutputDirectory
element without using a powershell script (which will only be run inside Visual Studio, not from the command prompt, on build servers or in other IDEs, and is not supported in project.json / xproj DNX projects) and I prefer to use a Link
to the files rather than having an additional copy of the files within the project.
Update:
Although this should also work with Content
rather than None
it appears that there's a bug in msbuild so files won't be copied to referencing projects more than one step removed (e.g. proj1 -> proj2 -> proj3, proj3 won't get the files from proj1's NuGet package but proj2 will).