There are several ways to tell the VS to copy dlls to the destination folder:
1.Add the dll as a resource of the project. And tell the VS to copy it if the dll is newer
2.Add a new project that reference to the dll project, and set the OutDir to the folder you want. This project does nothing but copy the dll.
3.Use a PostBuildEvent in vcxproj file
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
</ClCompile>
<Link>
</Link>
<PostBuildEvent>
<Command>
echo off
mkdir "$(ProjectDir)..\..\bin\$(Configuration)\"
copy "$(OutDir)xxx.dll" "$(ProjectDir)..\..\lib\$(Configuration)\"
echo on
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
4.Use a PreBuildEvent in vcxproj file
5.Use CustomBuild in vcxproj file
<ItemGroup>
<CustomBuild Include="..\..\xxx.dll">
<FileType>Document</FileType>
<Command>
call mkdir "$(OutDir)" 2>nul &
copy /Y "..\..\xxx.dll" "$(OutDir)xxx.dll"
</Command>
<Message>Copying xxx.dll to $(OutDir)\xxx.dll</Message>
<Outputs>$(OutDir)\xxx.dll</Outputs>
</CustomBuild>
</ItemGroup>
6.Use a makefile and copy dll in makefile. and use nmake to build
7.Write a bat file that do the copy job, and invoke the bat file as in 3-6
8.Use script such as python, which can also download the dll from internet. And invoke the py file as in 3-6.
9.Other build tools can help too, such as gradle
10.Make it a NuGet plugin
11.Sometimes I just write a bat, and execute the bat manually.
Update 01 (Self extract dll example):
1.Add you native dll as resource of managed dll
2.Add this init() method
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace DllSelfExtract
{
public class SelfExtract
{
public static void Init()
{
String managedDllPath = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;
String nativeDllPath = managedDllPath.Replace("file:///", "").Replace("DllSelfExtract.DLL", "TestDll.dll");
if(!File.Exists(nativeDllPath))
{
Stream dllIn = Assembly.GetExecutingAssembly().GetManifestResourceStream("DllSelfExtract.TestDll.dll");
if (dllIn == null) return;
using (Stream outFile = File.Create(nativeDllPath))
{
const int sz = 4096;
byte[] buf = new byte[sz];
while (true)
{
int nRead = dllIn.Read(buf, 0, sz);
if (nRead < 1)
break;
outFile.Write(buf, 0, nRead);
}
}
}
//LoadLibrary Here
}
}
}
3.In project that use your managed dll, invoke init() method first
SelfExtract.Init();
Update 02 (NuGet example):
1.Create a new NuGet project
2.Place the managed assemblies in the /lib directory
3.Place the non-managed shared libraries and related files in the /build subdirectory and rename all non-managed *.dll to *.dl_
4.Add a custom .targets file in the /build subdirectory with something like the following contents :
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<AvailableItemName Include="NativeBinary" />
</ItemGroup>
<ItemGroup>
<NativeBinary Include="$(MSBuildThisFileDirectory)*">
<TargetPath></TargetPath>
</NativeBinary>
</ItemGroup>
<PropertyGroup>
<PrepareForRunDependsOn>
$(PrepareForRunDependsOn);
CopyNativeBinaries
</PrepareForRunDependsOn>
</PropertyGroup>
<Target Name="CopyNativeBinaries" DependsOnTargets="CopyFilesToOutputDirectory">
<Copy SourceFiles="@(NativeBinary)"
DestinationFiles="@(NativeBinary->'$(OutDir)\%(TargetPath)\%(Filename).dll')"
Condition="'%(Extension)'=='.dl_'">
<Output TaskParameter="DestinationFiles" ItemName="FileWrites" />
</Copy>
<Copy SourceFiles="@(NativeBinary)"
DestinationFiles="@(NativeBinary->'$(OutDir)\%(TargetPath)\%(Filename).%(Extension)')"
Condition="'%(Extension)'!='.dl_'">
<Output TaskParameter="DestinationFiles" ItemName="FileWrites" />
</Copy>
</Target>
</Project>
5.Add build rule for build folder in Package.nuspec
<files>
<file src="lib\" target="lib" />
<file src="tools\" target="tools" />
<file src="content\" target="content" />
<file src="build\" target="build" />
</files>
6.Build the package
7.In your other C# project just add this NuGet package.