Есть ли лучшие способы скопировать собственную dll в папку bin?
у меня есть код оболочки C#, который вызывает функции из родной (c++) dll. В настоящее время я могу добавить ссылку на dll C# и установить параметр "копировать локальный" в true. Однако собственная dll, которая является зависимостью, не может быть добавлена в качестве ссылки-поэтому нет опции "копировать локально".
Я пробовал следующие подходы
-
использование событий после сборки для копирования собственной dll из папки Libs в
$(TargetFolder)
copy "$(ProjectDir)LibsNQuantLibc.dll" "$(TargetDir)NQuantLibc.dll"
включил собственную 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