我正在尝试为一个依赖于Ghostscript的库创建Nuget包,因此需要引用gsdll32.dll - 一种非托管库。我不能只将其作为标准dll引用程序包含在内。我应该将它放在Nuget目录结构的哪个位置?
我正在尝试为一个依赖于Ghostscript的库创建Nuget包,因此需要引用gsdll32.dll - 一种非托管库。我不能只将其作为标准dll引用程序包含在内。我应该将它放在Nuget目录结构的哪个位置?
在软件包中添加一个名为build
的文件夹,如果软件包的ID为MyPackage
,请将一个名为MyPackage.targets
的MSBuild目标文件添加到此文件夹中。重要的是,.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="CopyMyPackageFiles" AfterTargets="AfterBuild">
<ItemGroup>
<MyPackageFiles Include="$(MSBuildThisFileDirectory)..\lib\*.*"/>
</ItemGroup>
<Copy SourceFiles="@(MyPackageFiles)" DestinationFolder="$(OutputPath)" >
</Copy>
</Target>
</Project>
现在,包括未受管理的文件在内的所有文件将在构建后复制到项目输出文件夹中(例如\bin\debug)。
<?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目录中,因为Visual Studio看到第一个DLL依赖于第二个DLL。这是原始的nuspec参考。我主要是使用Lars Michael的方法来实现这个,但是我需要添加一个功能,这个功能来源于James Eby的回答。Visual Studio试图注册我lib
目录中的所有dll,所以我在nuspec文件的元数据中添加了一个references
元素,告诉它只注册托管的dll:
<references>
<reference file="FANNCSharp.dll" />
</references>
同时,在
<MyPackageFiles Include="$(MSBuildProjectDirectory)\..\Packages\MyPackage\lib\*.*"/>
我最初尝试使用我的包的ID FANNCSharp-x64
,但它需要完整的包名称:FANNCSharp-x64.0.1.4
。
在Nuget论坛上的回复:http://nuget.codeplex.com/discussions/352689
pranavkm: SQLCE包存在类似的问题,我们通过PS脚本来处理。可以查看位于 https://bitbucket.org/davidebbo/nugetpackages/src/1cba18b864f7/SqlServerCompact/Tools的这些脚本。
我曾经遇到的一个问题是,包路径相对于项目文件的位置并不总是一样。以下方法适用于我:
在NuGet包中,将非托管的DLL文件放在lib\native文件夹中。
将以下脚本添加到tools文件夹中:
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.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>
另请参阅: http://alski.net/post/2013/05/23/Using-NuGet-25-to-deliver-unmanaged-dlls.aspx
<file src="[source path for file in package]" target="runtimes\[platform]\native\[file name]" />
当执行应用程序时,运行时环境将在相应的平台目录中查找未管理的 dll 文件。
如果您想要针对多个平台进行定位,请为每个平台添加另一个文件条目。
<MyPackageFiles Include="$(MSBuildThisFileDirectory)..\myfile.dll
- Matthew Sharpelib
的文件夹中。 - Lars Michael