我如何使我的托pipeNuGet包支持C ++ / CLI项目?
当我从C#项目中使用它的时候,我做了一个NuGet包。 它包含lib/net40
目录中的一个DLL,并将该DLL作为参考添加。
既然NuGet支持C ++,那么我怎样才能真正修改我的包,以便可以在C ++ / CLI项目中将该DLL添加为托pipe引用? 我找不到解释这个的任何教程。 如果我尝试只是添加包,我得到以下错误:
您正在尝试将此软件包安装到以“Native,Version = v0.0”为目标的项目中,但该软件包不包含任何与该框架兼容的程序集引用或内容文件。
有人会认为解决scheme是把文件放在lib / native下,但根据http://docs.nuget.org/docs/reference/support-for-native-projects ,这是不支持的。 另外,简单地将DLL直接放在lib下,似乎没有任何作用。
显然,我应该用build / native下的.props
或.targets
文件来做到这一点,但是我需要将这些文件放到这些文件中才能使其工作?
正如Patrick O'Hara写的 ,NuGet不会为你改变一个C ++ / CLI项目。 请参阅GitHub问题NuGet / Home#1121 – 无法将托pipe软件包安装到CLI项目中 。 但是,使用NuGet命令行实用程序NuGet.exe
,可以让NuGet下载并解压所需的软件包。
作为一个完整的例子,下面是我在Visual Studio 2013 C ++ / CLI项目中添加对OptimizedPriorityQueue 1.0.0的引用的步骤:
- 打开软件包pipe理器控制台(如果尚未打开)( 工具> NuGet软件包pipe理器>软件包pipe理器控制台 )。
-
在包pipe理器控制台中,安装NuGet.CommandLine包:
安装包NuGet.CommandLine
(注意:在撰写本文时,最新版本的NuGet.CommandLine是2.8.6,可能与您不同。)
-
在您的项目文件夹中,现在应该有一个
.nuget\packages.config
XML文件,内容如下:<?xml version="1.0" encoding="utf-8"?> <packages> <package id="NuGet.CommandLine" version="2.8.6" /> </packages>
-
在文本编辑器(如Notepad ++)中,为所需的包添加一个
<package>
元素。 在这种情况下,我补充道:<package id="OptimizedPriorityQueue" version="1.0.0" />
..在
<packages>
元素中。 -
打开一个命令提示符(我打开了一个VS2013开发人员命令提示符,但是一个常规的命令提示符应该可以工作。)
-
cd
进入项目文件夹。 -
运行以下命令,更改NuGet.CommandLine的版本号(如果不同):
。\ packages \ NuGet.CommandLine.2.8.6 \ tools \ NuGet.exe安装-NonInteractive -OutputDirectory包.nuget \ packages.config
对我来说,输出是:
安装“OptimizedPriorityQueue 1.0.0.0”。 成功安装了“OptimizedPriorityQueue 1.0.0.0”。 packages.config中列出的所有软件包已经安装。
- 右键单击Visual Studio中的项目,然后select“ 属性” 。 在“ 通用属性”>“引用”下 ,单击“ 添加新引用…”button。
- select左侧的浏览 。 在Add Reference对话框的OK和Cancelbutton旁边,有一个Browse …button。 点击它打开一个文件select对话框。
- 导航到NuGet解压缩到您的项目文件夹的
packages
目录的DLL,然后单击添加button。 点击OKclosuresAdd Reference对话框。 -
您现在应该可以在C ++ / CLI项目中使用该程序集:
using namespace Priority_Queue; //...
正如对这个端口的回答( Nuget不会将entity framework安装到C ++ / CLI项目中 )所提到的,NuGet不会为你改变一个C ++ / CLI项目。 然而它会下载并解包你的依赖。 我们从命令行使用它作为我们的依赖关系的一部分。 命令行将如下所示:
/.NuGet/NuGet.exe Install -NonInteractive -ConfigFile $ENV{SRC_ROOT}/.nuget/NuGet.config -OutputDirectory $ENV{SRC_ROOT}/packages $ENV{SRC_ROOT}/packages.config
请注意,命令行参数被分隔成一行以使读取更容易。 我们还决定把NuGet放到我们的源代码控制的.NuGet文件夹中。 目标是让我们更容易地为我们的各种环境(不是所有的都使用Visual Studio)build立一个构build机器。 一旦你第一次运行这个命令,你必须手动添加依赖到你的C ++ / CLI项目。
希望有所帮助。
似乎实际上有可能使用以下步骤(至less在NuGet >= 2.5
)启用“常规”NuGet软件包并从C ++ / CLI项目自动引用:
-
将
build\<ProjectName>.targets
文件添加(或修改)到要打包的项目,并将下列内容放入其中(确保将<AssemblyName>
replace为实际值):<?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>
-
在打包项目的
.nuspec
中添加一个或多个file
条目,以便将程序集放在目标机器的lib\native\
目录中:<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>
即使NuGet不会将程序集引用添加到C ++ / CLI项目,它仍会插入由程序包提供的.props
和.targets
文件。 而来自步骤1的自定义目标将添加对我们的打包程序集的引用。
就我所见,这种解决scheme的一个缺点是,以这种方式添加的引用不会显示在C ++ / CLI项目的Commpon Properties/Framework and References
部分。 也可能有其他人,所以使用它自负风险…
安装程序尝试在C#启动项目中添加对自身的引用。 在安装之前,让C#在解决scheme中项目启动项目。 创build一个虚拟的C#项目,如果你没有一个
凭证实际上是使用添加软件包源的机器密钥encryption的。 除非使用纯文本变体,否则setApiKey命令可能应该作为构build的一部分运行。