.net 如何让我的托管 NuGet 包支持 C++/CLI 项目?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18694947/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I make my managed NuGet package support C++/CLI projects?
提问by Tor Hovland
I have made a NuGet package that works well when I use it from a C# project. It contains a DLL in the lib/net40directory, and the DLL gets added as a reference.
我制作了一个 NuGet 包,当我从 C# 项目中使用它时,它运行良好。它在lib/net40目录中包含一个 DLL ,该 DLL 被添加为引用。
Now that NuGet supports C++, how do I actually modify my package so that the DLL can be added as a managed reference in a C++/CLI project? I can't find any tutorials explaining this. If I try to just add the package as is, I get the following error:
既然 NuGet 支持 C++,我该如何实际修改我的包,以便可以将 DLL 添加为 C++/CLI 项目中的托管引用?我找不到任何解释这个的教程。如果我尝试按原样添加包,则会出现以下错误:
You are trying to install this package into a project that targets 'Native,Version=v0.0', but the package does not contain any assembly references or content files that are compatible with that framework.
您正在尝试将此包安装到以“Native,Version=v0.0”为目标的项目中,但该包不包含任何与该框架兼容的程序集引用或内容文件。
One would think that the solution is to put the files under lib/native, but according to http://docs.nuget.org/docs/reference/support-for-native-projects, that is not supported. Also, simply putting the DLL directly under lib doesn't seem to do anything.
有人会认为解决方案是将文件放在 lib/native 下,但根据http://docs.nuget.org/docs/reference/support-for-native-projects,这是不支持的。此外,简单地将 DLL 直接放在 lib 下似乎没有任何作用。
Apparently, I am supposed to do this with a .propsor .targetsfile under build/native, but what do I need to put into those files to make this work ?
显然,我应该使用build/native 下的.propsor.targets文件来执行此操作,但是我需要在这些文件中放入什么才能使其工作?
采纳答案by Daniel Trebbien
As Patrick O'Hara wrote, NuGet will not make changes to a C++/CLI project for you. See GitHub Issue NuGet/Home#1121 - Cannot install managed packages into a CLI project. However, using the NuGet command line utility, NuGet.exe, you can have NuGet download and unpack the desired package(s).
正如Patrick O'Hara 所写,NuGet 不会为您更改 C++/CLI 项目。请参阅GitHub 问题 NuGet/Home#1121 - 无法将托管包安装到 CLI 项目中。但是,使用 NuGet 命令行实用程序,NuGet.exe您可以让 NuGet 下载并解压所需的包。
For a complete example, here were steps that I took to add a reference to OptimizedPriorityQueue1.0.0 in a Visual Studio 2013 C++/CLI project:
对于一个完整的示例,以下是我在 Visual Studio 2013 C++/CLI 项目中添加对OptimizedPriorityQueue1.0.0的引用所采取的步骤:
- Open the Package Manager Console if not already open (TOOLS > NuGet Package Manager > Package Manager Console).
In the Package Manager Console, install the NuGet.CommandLine package:
Install-Package NuGet.CommandLine
(Note: As of this writing, the latest version of NuGet.CommandLine is 2.8.6. It may be different for you.)
Within your project folder, there should now be a
.nuget\packages.configXML file with the following contents:<?xml version="1.0" encoding="utf-8"?> <packages> <package id="NuGet.CommandLine" version="2.8.6" /> </packages>In a text editor such as Notepad++, add a
<package>element for the desired package. In this case, I added:<package id="OptimizedPriorityQueue" version="1.0.0" />.. within the
<packages>element.Open a command prompt (I opened a VS2013 Developer Command Prompt, but a regular command prompt should work.)
cdinto the project folder.Run the following command, changing the version number of NuGet.CommandLine if different:
.\packages\NuGet.CommandLine.2.8.6\tools\NuGet.exe Install -NonInteractive -OutputDirectory packages .nuget\packages.config
For me, the output was:
Installing 'OptimizedPriorityQueue 1.0.0.0'. Successfully installed 'OptimizedPriorityQueue 1.0.0.0'. All packages listed in packages.config are already installed.
- Right click on the project in Visual Studio and select Properties. Under Common Properties > References, click the Add New Reference…button.
- Select Browseon the left hand side. Next to the Add Reference dialog's OK and Cancel buttons, there is a Browse…button. Click that to open a file selection dialog.
- Navigate to the DLLs that NuGet unpacked to the
packagessubdirectory of your project folder and click the Addbutton. Click OKto close the Add Reference dialog. You should now be able to use the assembly in your C++/CLI project:
using namespace Priority_Queue; //...
- 如果尚未打开,请打开包管理器控制台(工具 > NuGet 包管理器 > 包管理器控制台)。
在包管理器控制台中,安装 NuGet.CommandLine 包:
Install-Package 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 Install -NonInteractive -OutputDirectory packages .nuget\packages.config
对我来说,输出是:
Installing 'OptimizedPriorityQueue 1.0.0.0'. Successfully installed 'OptimizedPriorityQueue 1.0.0.0'. All packages listed in packages.config are already installed.
- 在 Visual Studio 中右键单击该项目并选择Properties。在Common Properties > References 下,单击Add New Reference...按钮。
- 选择左侧的浏览。在 Add Reference 对话框的 OK 和 Cancel 按钮旁边,有一个Browse...按钮。单击它以打开文件选择对话框。
- 导航到 NuGet 解压到
packages项目文件夹子目录中的 DLL,然后单击“添加”按钮。单击“确定”关闭“添加引用”对话框。 您现在应该可以在 C++/CLI 项目中使用该程序集:
using namespace Priority_Queue; //...
回答by buygrush
There seem to be actually a possibility to enable "regular" NuGet packages to be installed and automatically referenced from C++/CLI projects using following steps (at least with NuGet >= 2.5):
实际上似乎有可能使用以下步骤(至少使用NuGet >= 2.5)来安装“常规”NuGet 包并从 C++/CLI 项目中自动引用:
Add (or modify) a
build\<ProjectName>.targetsfile to your project to be packaged and put following content into it (make sure to replace<AssemblyName>with an actual value):<?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>In the
.nuspecof the packaged project add one or morefileentries to also place the assembly inlib\native\directory at the target machine:<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>
build\<ProjectName>.targets在你的项目中添加(或修改)一个要打包的文件并将以下内容放入其中(确保替换<AssemblyName>为实际值):<?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>
Even if NuGet does not add assembly references to C++/CLI projects, it still inserts any .propsand .targetsfiles provided by a package. And the custom target from step 1 will add a reference to our packaged assembly.
即使 NuGet 不向 C++/CLI 项目添加程序集引用,它仍会插入包提供的任何.props和.targets文件。步骤 1 中的自定义目标将添加对我们打包程序集的引用。
One drawbackof this solution, as far as I could see it, is that the reference added in such a way is not displayed in the Commpon Properties/Framework and Referencessection of the C++/CLI project. There may also be others, so use it at your own risk...
据我所知,此解决方案的一个缺点是,以这种方式添加的引用未显示在Commpon Properties/Framework and ReferencesC++/CLI 项目的部分中。可能还有其他的,所以使用它需要你自担风险......
回答by Patrick O'Hara
As mentioned in the answer to this port (Nuget won't install Entity Framework into C++/CLI project), NuGet will not make the changes to a C++/CLI project for you. It will however download and unpackage the dependency for you. We use it from the command line as part of our make dependencies. The command line will look something like this:
正如对此端口的回答中所述(Nuget 不会将实体框架安装到 C++/CLI 项目中),NuGet 不会为您更改 C++/CLI 项目。但是,它会为您下载并解包依赖项。我们从命令行使用它作为我们的 make 依赖项的一部分。命令行看起来像这样:
/.NuGet/NuGet.exe
Install
-NonInteractive
-ConfigFile $ENV{SRC_ROOT}/.nuget/NuGet.config
-OutputDirectory $ENV{SRC_ROOT}/packages
$ENV{SRC_ROOT}/packages.config
Note that the command line areguments are separated one to a line to make reading easier. Also we decided to check NuGet into our source control un the .NuGet folder. The goal was to make it easier to setup a build machine for our various environments (not all of which use Visual Studio). Once you have run this command for the first time, you must manually add the dependencies to your C++/CLI project.
Hope that helps.
请注意,命令行参数被分隔成一行,以便于阅读。我们还决定将 NuGet 签入我们的源代码控制中的 .NuGet 文件夹。目标是更容易为我们的各种环境(并非所有环境都使用 Visual Studio)设置构建机器。首次运行此命令后,您必须手动将依赖项添加到 C++/CLI 项目中。
希望有帮助。
回答by Mikael
The installer tries to add a reference to itself in the C# startup project. Make a C# project the startup project in the solution before install. Create a dummy C# project if you do not have one
安装程序尝试在 C# 启动项目中添加对自身的引用。安装前将解决方案中的启动项目设为 C# 项目。如果没有,请创建一个虚拟的 C# 项目
回答by Chandra
Easy workaround is to wrap such NuGet in a regular .NET project (C#) and reference the same in your C++/CLI project.
简单的解决方法是将此类 NuGet 包装在常规 .NET 项目 (C#) 中,并在 C++/CLI 项目中引用相同的内容。
回答by Omar H
Credentials are actually encrypted with the machinekey where the package source was added. Unless using the plaintext variant, the setApiKey command should probably be run as part of the build.
凭据实际上是使用添加包源的机器密钥加密的。除非使用纯文本变体,否则 setApiKey 命令可能应该作为构建的一部分运行。

