2012-04-17 20 views

Respuesta

8

La referencia anterior puede funcionar, pero en realidad modifica su evento de creación posterior para empujar los archivos, lo que puede no solucionar realmente su problema si tiene la situación que tuvimos.

El problema que teníamos era que una DLL dependiente no podía registrarse, pero tenía que existir al lado de otra DLL que necesitaba ser registrada por nuget , por lo que necesitaba existir en el directorio lib pero no estar registrada.

La referencia nuspec ahora le permite especificar qué archivos DLL en el directorio lib se registren de forma explícita en el proyecto de Visual Studio ahora, sólo hay que añadir en el archivo de nuspec en la zona metadatos un explícitas referencias list (si esto no existe, el comportamiento predeterminado de nuget es intentar registrar todo bajo lib).

Aquí es un archivo nuspec ejemplo de lo que quiero decir:

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

Como se puede ver, ceTe.DynamicPDF.Rasterizer.20.x86.dll necesita ser registrado, pero DPDFRast.x86.dll simplemente tiene que existir en ese directorio para apoyar al otro DLL y ganaron' t se registrará pero a través de alguna magia de referencia dinámica finalmente se copiará en el directorio de destino bin porque Visual Studio ve que la primera DLL depende de la segunda.

Aquí está el original nuspec reference.

+1

_ "... a través de alguna magia de referencia dinámica finalmente se copiará en el directorio bin de destino de todos modos ..." _. Esto parece no estar funcionando para dll ** sin control, que es de lo que se trata la pregunta. –

+1

DPDFRast.x86.dll es una DLL no administrada. –

+3

Bueno, no funcionó en mi caso, pero http://stackoverflow.com/a/33041626/798781 sí. –

11

Agregue una carpeta build al paquete y, si el paquete, por ejemplo, tiene el id MyPackage, agregue un archivo de destino de MSBuild llamado MyPackage.targets a esta carpeta. Es importante que el archivo .targets tenga el mismo nombre que el archivo .nuspec. En el archivo .nuspec debe tener una sección como esta:

<files> 
    <file src="lib\*.*" target="lib" /> 
    <file src="build\MyPackage.targets" target="build" /> 
</files> 

Esto añadirá un elemento de MSBuild en el archivo de proyecto que apunta al archivo .targets.

Por otra parte, sólo a registrar los archivos DLL administrados, añadir una sección como esta:

<references> 
    <reference file="MyManaged.dll" /> 
</references> 

El archivo .targets debería ser algo como esto:

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

Ahora, todos archivos - incluyendo archivos no administrados: se copiarán en la carpeta de salida del proyecto (por ejemplo, \ bin \ debug) después de la compilación.

+0

Agradezco este Lars. ¿Puedes editarlo en tu respuesta? Los enlaces a blogs tienden a dejar de funcionar. –

+0

usted hizo mi día (período). –

+0

No entiendo en absoluto cómo funciona esto.Hago exactamente lo que estás diciendo, luego genero mi archivo .nupkg y hago referencia a este archivo en mi proyecto. Pero cuando construyo nada, lo que escribí en mi archivo MyPackage.targets se ejecuta. He intentado la tarea de Mensaje con gran Importancia, pero nada cambia. Una vez que se crea el paquete, todos los archivos dll y nuspec son inútiles ¿no? –

1

Un problema que tuve fue que la ruta de los paquetes no siempre estaba en el mismo lugar que el archivo del proyecto. Lo siguiente funcionó para mí:

  1. Dentro del paquete NuGet, coloque sus archivos DLL no administrados en la carpeta lib \ native.

  2. Añadir la siguiente secuencia de comandos en la carpeta de herramientas:

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) 
  1. Añadir un archivo de objetivos a la carpeta de compilación. (Cambia "MyPackage" al nombre de tu paquete). El uso de un nombre único para el objetivo, como "CopyMyPackage", evita conflictos con otros paquetes que intentan definir el objetivo "AfterBuild". Este archivo de objetivos hace uso de la propiedad $ (PackagesPath) definida por el script anterior.

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> 
  1. Por último, añadir un "MyPackageReadMe.txt" a la carpeta de contenido. Esto permitirá que el paquete se instale.

Consulte también: http://alski.net/post/2013/05/23/Using-NuGet-25-to-deliver-unmanaged-dlls.aspx

3

llegué en gran medida que esto funcione utilizando el método de Lars Michael, pero una cosa que tenía que añadir proviene de la respuesta de James Eby. Visual Studio estaba tratando de registrar todas las DLL en mi directorio lib, por lo que añade un elemento de references a los metadatos en el archivo nuspec para decirle que solamente registrar la DLL administrada:

<references> 
    <reference file="FANNCSharp.dll" />   
</references> 

También en

<MyPackageFiles Include="$(MSBuildProjectDirectory)\..\Packages\MyPackage\lib\*.*"/> 

Primero probé la identificación de mi paquete FANNCSharp-x64, pero necesitaba el nombre completo del paquete: FANNCSharp-x64.0.1.4.

+1

Modifiqué la respuesta original para abordar las cosas que menciona. Gracias . –

Cuestiones relacionadas