Есть ли лучшие способы скопировать собственную dll в папку bin?

у меня есть код оболочки C#, который вызывает функции из родной (c++) dll. В настоящее время я могу добавить ссылку на dll C# и установить параметр "копировать локальный" в true. Однако собственная dll, которая является зависимостью, не может быть добавлена в качестве ссылки-поэтому нет опции "копировать локально".

Я пробовал следующие подходы

  1. использование событий после сборки для копирования собственной dll из папки Libs в $(TargetFolder)

    copy "$(ProjectDir)LibsNQuantLibc.dll" "$(TargetDir)NQuantLibc.dll"

  2. включил собственную dll в качестве существующего элемента в проект (добавить -> существующий элемент -> включить dll). Эта опция позволяет мне использовать опцию "копировать локально". Недостатком этого подхода является то, что dll всегда отображается как элемент проекта.

Я также попытался "показать все файлы", что позволило мне увидеть папку Libs. Затем я включаю NQuantLibc.DLL файл в проект, который позволил мне установить копию Местный вариант. Однако это дало неожиданный результат. Он создал подпапку Libs, содержащую dll в папке bin (например,bin/debug/Libs/NQuantLibc.dll). Не идеально, так как dll c# не смогла правильно вызвать родную dll, так как ее там не было.

оба вышеуказанных варианта выше работают. Есть ли лучшие способы скопировать собственную dll в папку bin, чтобы зависимость всегда разрешалась? В качестве альтернативы, существует ли другой подход к этому типу сценария?

6 ответов


используйте Project + добавить существующий элемент и выберите DLL. Выберите добавленный файл в окне Обозреватель решений. В окне Свойства измените параметр копировать в выходной каталог на "копировать, если новее".


вы можете добавить собственную dll в качестве связанного элемента и использовать"копировать, если новее".
Проблема с собственными библиотеками DLL заключается в том, что иногда вы захотите использовать разные библиотеки DLL в соответствии с конфигурацией проекта (Debug/Release или platform).

вы можете редактировать проект .csproj и связать родную dll условно:

 <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>

Примечание параметр копировать имеет значение PreserveNewest что означает "копировать, если новее".


нашел лучший способ. Nuget может добавить .целевые файлы, ведьма хранятся в папке сборки пакета, в ваш проект. Таким образом, вы можете копировать при каждой сборке некоторые файлы вашего пакета, где хотите. В следующем примере я сохранил некоторую не DotNet DLL в папку" двоичные файлы". При каждой сборке он проверяет, скопированы ли библиотеки DLL в выходную папку (переменная$OutputPath), и при необходимости копирует их.

содержание Nuspec :

<?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>

пример.содержание целей:

<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>

добавьте dll в качестве файла в проект ("как ссылка", возможно, если вы все еще хотите, чтобы он находился в другом каталоге). Затем установите действие сборки в content и скопируйте в выходной каталог в true.


Если вы в порядке с созданной папкой "Libs", вы можете попробовать добавить ее в путь поиска для вашего приложения, добавив следующее в :

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <probing privatePath="Libs;Bin2"/>
      </assemblyBinding>
   </runtime>
</configuration>

это приведет к тому, что среда выполнения будет искать во всех указанных каталогах DLL.

редактировать к сожалению, этот не влияет на неуправляемую загрузку DLL DllImport.


по-видимому, у меня была такая же проблема, но я не хотел так много редактировать файл проекта, поэтому я использовал следующий скрипт после сборки:

xcopy /y "$(ProjectDir)\lib_$(Platform)\*.dll" "$(ProjectDir)$(OutDir)"

просто убедитесь, что у вас есть папки для каждой платформы таргетинга, например: lib_x86, lib_x64 а может быть lib_AnyCPU