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 the native dll, which is a dependency, cannot be added as a reference - so there is no 'Copy Local' option.
I have tried the following approaches
Using a post-build events to copy the native dll from the Libs folder to the
$(TargetFolder)
copy "$(ProjectDir)Libs\NQuantLibc.dll" "$(TargetDir)NQuantLibc.dll"
Included the native dll as an existing item in the project (Add -> Existing Item -> Include dll). This option allows me to use the 'Copy Local' option. The downside to this approach is that the dll always shows as a project item.
I also tried "Show All Files" which allowed me to see the Libs folder. I then include the NQuantLibc.dll file in the project which allowed me to set the 'Copy Local' option. However, this gave me a unexpected result. It created a Libs subfolder containing the dll within the bin folder (eg bin/debug/Libs/NQuantLibc.dll
). Not ideal since the C# dll was not able to properly call the native dll since it was not there.
Both of the above options above work. Are there any better ways to copy a native dll to the bin folder such that the dependency will always be resolved? Alternatively, is there a different approach to this type of scenario?
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: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.
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:
Note the copy option is set to PreserveNewest which means "copy if newer".
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 :
Example.targets content :
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 maybelib_AnyCPU
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".