visual studio standard nupkg net framework create .net dll c++-cli nuget nuget-package

.net - studio - ¿Cómo puedo hacer que mi paquete gestionado NuGet soporte proyectos C++/CLI?



nuget package explorer (5)

He hecho un paquete NuGet que funciona bien cuando lo uso desde un proyecto C #. Contiene una DLL en el directorio lib/net40 y la DLL se agrega como referencia.

Ahora que NuGet admite C ++, ¿cómo modifico mi paquete para que la DLL se pueda agregar como referencia administrada en un proyecto de C ++ / CLI? No puedo encontrar ningún tutorial que explique esto. Si intento simplemente agregar el paquete como está, obtengo el siguiente error:

Está intentando instalar este paquete en un proyecto que se dirige a ''Native, Version = v0.0'', pero el paquete no contiene ninguna referencia de ensamblado ni archivos de contenido que sean compatibles con ese marco.

Uno podría pensar que la solución es poner los archivos en lib / native, pero de acuerdo con http://docs.nuget.org/docs/reference/support-for-native-projects , eso no es compatible. Además, simplemente poner el DLL directamente bajo lib no parece hacer nada.

Aparentemente, se supone que debo hacer esto con un archivo .props o .targets en compilación / nativo, pero ¿qué necesito poner en esos archivos para que esto funcione?


Como escribió Patrick O''Hara , NuGet no hará cambios en un proyecto de C ++ / CLI por usted. Ver GitHub Issue NuGet / Home # 1121 - No se pueden instalar paquetes administrados en un proyecto de CLI . Sin embargo, usando la utilidad de línea de comandos NuGet.exe , NuGet.exe , puede hacer que NuGet descargue y descomprima los paquetes deseados.

Para un ejemplo completo, aquí hay pasos que tomé para agregar una referencia a OptimizedPriorityQueue 1.0.0 en un proyecto de Visual Studio 2013 C ++ / CLI:

  1. Abra la consola de Package Manager si aún no está abierta ( HERRAMIENTAS> NuGet Package Manager> Package Manager Console ).
  2. En la consola de Package Manager, instale el paquete NuGet.CommandLine:

    Install-Package NuGet.CommandLine

    (Nota: Al escribir estas líneas, la última versión de NuGet.CommandLine es 2.8.6. Puede ser diferente para usted).

  3. Dentro de la carpeta del proyecto, ahora debe haber un archivo XML .nuget/packages.config con los siguientes contenidos:

    <?xml version="1.0" encoding="utf-8"?> <packages> <package id="NuGet.CommandLine" version="2.8.6" /> </packages>

  4. En un editor de texto como Notepad ++, agregue un elemento <package> para el paquete deseado. En este caso, agregué:

    <package id="OptimizedPriorityQueue" version="1.0.0" />

    .. dentro del elemento <packages> .

  5. Abra un símbolo del sistema (abrí un símbolo del sistema de desarrollador VS2013, pero un símbolo del sistema normal debería funcionar).

  6. cd en la carpeta del proyecto.
  7. Ejecute el siguiente comando, cambiando el número de versión de NuGet.CommandLine si es diferente:

    ./packages/NuGet.CommandLine.2.8.6/tools/NuGet.exe Install -NonInteractive -OutputDirectory packages .nuget/packages.config

    Para mí, la salida fue:

    Installing ''OptimizedPriorityQueue 1.0.0.0''. Successfully installed ''OptimizedPriorityQueue 1.0.0.0''. All packages listed in packages.config are already installed.

  8. Haga clic con el botón derecho en el proyecto en Visual Studio y seleccione Propiedades . En Propiedades comunes> Referencias , haga clic en el botón Agregar nueva referencia ...
  9. Seleccione Buscar en el lado izquierdo. Junto a los botones Aceptar y Cancelar del cuadro de diálogo Agregar referencia, hay un botón Examinar ... Haga clic en eso para abrir un diálogo de selección de archivo.
  10. Navegue a los archivos DLL que NuGet desempaquetó en el subdirectorio de packages de su carpeta de proyecto y haga clic en el botón Agregar . Haga clic en Aceptar para cerrar el cuadro de diálogo Agregar referencia.
  11. Ahora debería poder usar el ensamblado en su proyecto C ++ / CLI:

    using namespace Priority_Queue; //...


Como se menciona en la respuesta a este puerto ( Nuget no instalará Entity Framework en el proyecto C ++ / CLI ), NuGet no realizará los cambios en un proyecto de C ++ / CLI por usted. Sin embargo, descargará y desempaquetará la dependencia por usted. Lo usamos desde la línea de comando como parte de nuestras dependencias make. La línea de comando se verá algo así:

/.NuGet/NuGet.exe Install -NonInteractive -ConfigFile $ENV{SRC_ROOT}/.nuget/NuGet.config -OutputDirectory $ENV{SRC_ROOT}/packages $ENV{SRC_ROOT}/packages.config

Tenga en cuenta que los argumentos de la línea de comandos están separados uno a una línea para facilitar la lectura. También decidimos comprobar NuGet en nuestro control de origen en la carpeta .NuGet. El objetivo era facilitar la configuración de una máquina de construcción para nuestros diversos entornos (no todos utilizan Visual Studio). Una vez que haya ejecutado este comando por primera vez, debe agregar manualmente las dependencias a su proyecto C ++ / CLI.
Espero que ayude.


El instalador intenta agregar una referencia a sí mismo en el proyecto de inicio de C #. Haga que un proyecto de C # sea el proyecto de inicio en la solución antes de la instalación. Crea un proyecto ficticio C # si no tienes uno


Las credenciales en realidad están cifradas con la clave de máquina donde se agregó el origen del paquete. A menos que se use la variante de texto plano, el comando setApiKey probablemente debería ejecutarse como parte de la compilación.


Parece que hay una posibilidad de habilitar paquetes NuGet "regulares" para ser instalados y referidos automáticamente desde proyectos C ++ / CLI usando los siguientes pasos (al menos con NuGet >= 2.5 ):

  1. Agregue (o modifique) un archivo build/<ProjectName>.targets a su proyecto para empaquetarlo y poner el siguiente contenido en él (asegúrese de reemplazar <AssemblyName> con un valor real):

    <?xml version="1.0" encoding="utf-8" ?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <!-- for C++/CLI projects only --> <ItemGroup Condition="''$(Language)'' == ''C++''"> <Reference Include="<AssemblyName>"> <!-- this .targets file is installed next to the assembly, so we do not have to figure out any versions or paths here ourselves --> <HintPath> $(MSBuildThisFileDirectory)../lib/native/<AssemblyName>.dll </HintPath> </Reference> </ItemGroup> </Project>

  2. En el .nuspec del proyecto empaquetado, agregue una o más entradas de file para colocar también el ensamblado en el directorio lib/native/ en la máquina de destino:

    <package> <metadata> ... </metadata> <files> ... <!-- add a copy of the assembly to lib/native to prevent NuGet from complaining about incompatible native projects --> <file src="bin/$configuration$/$id$.dll" target="lib/native/" /> <file src="bin/$configuration$/$id$.xml" target="lib/native/" /> <!-- don''t forget about the .targets file containing the reference --> <file src="build/$id$.targets" target="build/" /> </files> ... </package>

Incluso si NuGet no agrega referencias de ensamblado a proyectos C ++ / CLI, aún inserta cualquier .props y .targets proporcionado por un paquete. Y el objetivo personalizado del paso 1 agregará una referencia a nuestro ensamblado empaquetado.

Una desventaja de esta solución, por lo que pude ver, es que la referencia añadida de esa manera no se muestra en la Commpon Properties/Framework and References del proyecto C ++ / CLI. También puede haber otros, así que úsala bajo tu propio riesgo ...