NuGet: Где разместить DLL для неуправляемых библиотек?
Я пытаюсь создать пакет Nuget для библиотеки, которая зависит от ghostscript и поэтому ссылки gsdll32.dll - неуправляемая библиотека. Я не могу просто включить стандартную ссылку dll. Где я могу поместить это в структуру каталогов nuget?
Ответы
Ответ 1
Добавьте в пакет папку build
, и если пакет, например, имеет идентификатор MyPackage
, добавьте целевой файл MSBuild с именем MyPackage.targets
в эту папку. Важно, чтобы файл .targets
имел то же имя, что и файл .nuspec
. В файле .nuspec
у вас должен быть такой раздел:
<files>
<file src="lib\*.*" target="lib" />
<file src="build\MyPackage.targets" target="build" />
</files>
Это добавит элемент MSBuild в файл проекта, указывающий на файл .targets
.
Кроме того, чтобы регистрировать управляемые DLL, добавьте раздел, подобный этому:
<references>
<reference file="MyManaged.dll" />
</references>
Файл .targets
должен выглядеть примерно так:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="AfterBuild">
<ItemGroup>
<MyPackageFiles Include="$(MSBuildThisFileDirectory)..\lib\*.*"/>
</ItemGroup>
<Copy SourceFiles="@(MyPackageFiles)" DestinationFolder="$(OutputPath)" >
</Copy>
</Target>
</Project>
Теперь все файлы, включая неуправляемые файлы, будут скопированы в выходную папку проекта (например,\bin\debug) после сборки.
Ответ 2
Вышеуказанная ссылка может работать, но на самом деле она изменяет ваше событие post build, чтобы перетаскивать файлы, что на самом деле не может исправить вашу проблему, если у вас есть ситуация, которую мы сделали.
Проблема, с которой мы столкнулись, была зависимой DLL, не может быть зарегистрирована, но она должна существовать бок о бок с другой DLL, которую нужно было зарегистрировать nuget , поэтому она должна существовать в каталоге lib, но не регистрироваться.
Ссылка nuspec теперь позволяет вам указать, какие DLL файлы в каталоге lib получить явным образом зарегистрированы в проекте визуальной студии сейчас, вам просто нужно добавить в свой файл nuspec в метаданных /strong > в явном списке ссылок (если этого не существует, поведение nuget по умолчанию заключается в попытке зарегистрировать все в lib).
Вот пример файла nuspec, что я имею в виду:
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>SomePackageID</id>
<version>1.0.1</version>
<title>Some Package Title</title>
<authors>Some Authors</authors>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Blah blah blah.</description>
<references>
<reference file="ceTe.DynamicPDF.Rasterizer.20.x86.dll" />
</references>
</metadata>
<files>
<file src="\\SomeNetworkLocation\ceTe.DynamicPDF.Rasterizer.20.x86.dll" target="lib\ceTe.DynamicPDF.Rasterizer.20.x86.dll" />
<file src="\\SomeNetworkLocation\DPDFRast.x86.dll" target="lib\DPDFRast.x86.dll" />
</files>
</package>
Как вы можете видеть, ceTe.DynamicPDF.Rasterizer.20.x86.dll
необходимо зарегистрировать, но DPDFRast.x86.dll
просто должен существовать в этом каталоге для поддержки другой DLL и не будет зарегистрирован, но через некоторую динамическую магию ссылок в конечном итоге будет скопирован в каталог назначения bin, так как визуальная студия видит, что первая DLL зависит от второй.
Вот оригинальная ссылка на nuspec.
Ответ 3
Ответ на форуме Nuget: http://nuget.codeplex.com/discussions/352689
pranavkm: У пакета SQLCE есть аналогичная проблема, с которой мы справляемся через PS скрипты. Оформить сценарии в https://bitbucket.org/davidebbo/nugetpackages/src/1cba18b864f7/SqlServerCompact/Tools.
Ответ 4
В основном я использовал это, используя метод Ларса Майкла, но мне нужно было добавить одну вещь, полученную от Джеймса Эби. Visual Studio пыталась зарегистрировать всю DLL в моем каталоге lib
, поэтому я добавил элемент references
в метаданные в файле nuspec, чтобы сообщить ему только зарегистрировать управляемую DLL:
<references>
<reference file="FANNCSharp.dll" />
</references>
Также в
<MyPackageFiles Include="$(MSBuildProjectDirectory)\..\Packages\MyPackage\lib\*.*"/>
Сначала я попробовал идентификатор моего пакета FANNCSharp-x64
, но ему было нужно полное имя пакета: FANNCSharp-x64.0.1.4
.
Ответ 5
Одна из проблем заключалась в том, что путь пакетов не всегда находился в одном и том же месте по сравнению с файлом проекта. Для меня работали следующие:
install.ps1
#This script creates or updates a PackagesPath property in the project file
param($installPath, $toolsPath, $package, $project)
$project.Save()
#Load the csproj file into an xml object
[xml] $xml = Get-Content -path $project.FullName
#grab the namespace from the project element
$nsmgr = New-Object System.Xml.XmlNamespaceManager -ArgumentList $xml.NameTable
$nsmgr.AddNamespace('a',$xml.Project.GetAttribute("xmlns"))
#find or create the property
$property = $xml.Project.SelectSingleNode("//a:PropertyGroup//a:PackagesPath", $nsmgr)
if (!$property)
{
$property = $xml.CreateElement("PackagesPath", $xml.Project.GetAttribute("xmlns"))
$propertyGroup = $xml.CreateElement("PropertyGroup", $xml.Project.GetAttribute("xmlns"))
$propertyGroup.AppendChild($property)
$xml.Project.InsertBefore($propertyGroup, $xml.Project.ItemGroup[0])
}
#find the relative path to the packages folder
$absolutePackagesPath = (get-item $installPath).parent.FullName
push-location (split-path $project.FullName)
$relativePackagesPath = Resolve-Path -Relative $absolutePackagesPath
pop-location
#set the property value
$property.InnerText = $relativePackagesPath
#save the changes.
$xml.Save($project.FullName)
- Добавить файл целей в папку сборки. (Измените "MyPackage" на название вашего пакета). Использование уникального имени для цели, например "CopyMyPackage", позволяет избежать конфликтов с другими пакетами, которые пытаются определить цель "AfterBuild". Этот файл целей использует свойство $(PackagesPath), определенное выше script.
MyPackage.targets
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="CopyMyPackage" AfterTargets="AfterBuild">
<ItemGroup>
<MyPackageSourceFiles Include="$(PackagesPath)\MyPackage.*\lib\native\*.*"/>
</ItemGroup>
<Copy SourceFiles="@(MyPackageSourceFiles)" DestinationFolder="$(OutputPath)" >
</Copy>
</Target>
</Project>
- Наконец, добавьте "MyPackageReadMe.txt" в папку "Содержимое". Это позволит установить пакет.
Смотрите также: http://alski.net/post/2013/05/23/Using-NuGet-25-to-deliver-unmanaged-dlls.aspx