I have C# wrapper code that calls functions from a native (C++) dll. Currently, I can add a reference to the C# dll and have set the \'Copy Local\' option to true. However t
Use Project + Add Existing Item and select the DLL. Select the added file in the Solution Explorer window. In the Properties window, change the Copy to Output Directory setting to "Copy if newer".
Apparently I happened to have the same problem, but I did not want to do project file editing so much, so I ended up using following post-build script:
xcopy /y "$(ProjectDir)\lib_$(Platform)\*.dll" "$(ProjectDir)$(OutDir)"
Just make sure you have a folder for every targeting platform needed, e.g.: lib_x86
, lib_x64
and maybe lib_AnyCPU
Found a better way. Nuget can add .targets files, witch are stored in the build folder of the package, into your project. With this way you can copy at each build some files of your package wherever you want. In the following example, I have stored some Non DotNet DLL into a "binaries" folder. At each build, It checks if DLLs are already copied in the output folder ($OutputPath variable) and copy them if necessary.
Nuspec content :
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Example</id>
<version>1.0.0</version>
<authors>Example</authors>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Example</description>
</metadata>
<files>
<file src="Non-DotNet.dll" target="binaries\Non-DotNet.dll" />
<file src="DotNet.dll" target="lib\net40\DotNet.dll" />
<file src="Example.targets" target="build\Example.targets" />
</files>
</package>
Example.targets content :
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="CopyBinaries" BeforeTargets="BeforeBuild">
<CreateItem Include="$(MSBuildThisFileDirectory)..\binaries\**\*.*">
<Output TaskParameter="Include" ItemName="PackageBinaries" />
</CreateItem>
<Copy SourceFiles="@(PackageBinaries)"
DestinationFolder="$(OutputPath)"
SkipUnchangedFiles="true"
OverwriteReadOnlyFiles="true"
/>
</Target>
</Project>
You can add the native dll as a linked item, and use "Copy if newer".
The problem with native dlls, is that sometimes you'll want to use different dlls according to the project's configuration (Debug/Release or platform).
You can edit the project's .csproj and link the native dll conditionally:
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|Win32' ">
<Content Include="..\..\bin\Win32\Release\NQuantLibc.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|Win32' ">
<Content Include="..\..\bin\Win32\Debug\NQuantLibc_d.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
<Content Include="..\..\bin\x64\Debug\NQuantLibc_d.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
<Content Include="..\..\bin\x64\Release\NQuantLibc.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
Note the copy option is set to PreserveNewest which means "copy if newer".
If you're OK with the created "Libs" folder, you can try adding it to the probing path for your application, by adding the following in the app.config
file:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="Libs;Bin2"/>
</assemblyBinding>
</runtime>
</configuration>
This will cause the runtime to look in all the specified directories for the DLL.
EDIT Unfortunately, this does not impact the unmanaged DLL loading by DllImport.
Add the dll as a file in the project ("As link" maybe if u still want it to reside in another directory). Then set the Build Action to content and Copy to output directory to true.