在何处放置非托管库的DLL?
我正在尝试为一个依赖于ghostscript的库创建一个Nuget包,因此它引用了gsdll32.dll—一个非托管库。我不能只是把它包含在标准dll引用中。我应该把它放在nuget目录结构的什么地方?nuget论坛上的回应: pranavkm: SQLCE包有一个类似的问题,我们通过PS来处理 脚本。签出脚本在在何处放置非托管库的DLL?,dll,dependencies,unmanaged,nuget,Dll,Dependencies,Unmanaged,Nuget,我正在尝试为一个依赖于ghostscript的库创建一个Nuget包,因此它引用了gsdll32.dll—一个非托管库。我不能只是把它包含在标准dll引用中。我应该把它放在nuget目录结构的什么地方?nuget论坛上的回应: pranavkm: SQLCE包有一个类似的问题,我们通过PS来处理 脚本。签出脚本在 上面的引用可以工作,但它实际上修改了构建后事件以将文件推送过来,如果您遇到了我们所遇到的情况,这实际上可能无法解决您的问题 我们遇到的问题是一个依赖DLL无法注册,但必须与另一个需要
上面的引用可以工作,但它实际上修改了构建后事件以将文件推送过来,如果您遇到了我们所遇到的情况,这实际上可能无法解决您的问题 我们遇到的问题是一个依赖DLL无法注册,但必须与另一个需要由nuget注册的DLL并排存在,因此它需要存在于lib目录中,但不能注册。 nuspec引用现在允许您指定在visual studio项目中显式注册lib目录中的哪些DLL。现在,您只需在元数据区域的nuspec文件中添加显式引用列表(如果不存在,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>
一些包装
1.0.1
一些包裹的标题
有这样一个部分:
<files>
<file src="lib\*.*" target="lib" />
<file src="build\MyPackage.targets" target="build" />
</files>
<references>
<reference file="MyManaged.dll" />
</references>
<?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>
.targets
文件应如下所示:
<files>
<file src="lib\*.*" target="lib" />
<file src="build\MyPackage.targets" target="build" />
</files>
<references>
<reference file="MyManaged.dll" />
</references>
<?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)。我遇到的一个问题是,相对于项目文件,包路径并不总是在同一个位置。以下操作对我有效:
在NuGet包中,将非托管DLL放在lib\native文件夹中
将以下脚本添加到“工具”文件夹:
安装.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”目标的其他包发生冲突。此目标文件使用上述脚本定义的$(PackagePath)属性
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”。这将使软件包能够安装
另请参见:我基本上是使用Lars Michael的方法实现的,但我需要添加一件事,这来自James Eby的回答。Visual Studio试图注册我的lib
目录中的所有dll,因此我在nuspec文件的元数据中添加了引用
元素,告诉它只注册托管dll:
<references>
<reference file="FANNCSharp.dll" />
</references>
也在
<MyPackageFiles Include="$(MSBuildProjectDirectory)\..\Packages\MyPackage\lib\*.*"/>
我首先尝试了我的包的idFANNCSharp-x64
,但它需要完整的包名:FANNCSharp-x64.0.1.4
“…通过一些动态引用魔法最终将被复制到目标bin目录中…”。这似乎对未更改的dll不起作用,这就是问题所在。好吧,它在我的情况下不起作用,但确实起了作用。我很感激这个Lars-你能将它编辑到你的答案中吗?博客链接往往会停止工作。你让我过了一天(句号)。@Jérôme有点晚了,但我认为你的问题仍然值得回答。有轻微的问题(而且绝对不明显).target文件的陷阱:名称必须与包名称相同。如果是这样,在包安装时,目标会自动添加到.csproj文件中。您可以在接近末尾的某个包中检查是否引用了您的目标。只有这样,它才会起作用。不涉及其他魔法。您可以避免硬编码精确路径,如下所示:@elliotwods在.nuspec文件()中…目标文件需要根据您放置本机文件的位置进行自定义。在本例中,它们被放置在名为lib
的文件夹中。我修改了原始答案以解决您提到的问题。谢谢。