如何使我的托管NuGet包支持C++/CLI项目?

Tor*_*and 68 .net dll c++-cli nuget nuget-package

我已经制作了一个NuGet包,当我从C#项目中使用它时效果很好.它在lib/net40目录中包含一个DLL ,并且DLL被添加为引用.

现在NuGet支持C++,我如何实际修改我的包,以便可以在C++/CLI项目中将DLL添加为托管引用?我找不到任何解释这个的教程.如果我尝试按原样添加包,则会收到以下错误:

您正在尝试将此软件包安装到以"Native,Version = v0.0"为目标的项目中,但该软件包不包含任何与该框架兼容的程序集引用或内容文件.

有人会认为解决方案是将文件放在lib/native下,但根据http://docs.nuget.org/docs/reference/support-for-native-projects,这是不受支持的.此外,简单地将DLL直接放在lib下似乎没有做任何事情.

显然,我应该使用build/native下的文件.props.targets文件来执行此操作,但是我需要将这些文件放入这些文件中以使其工作?

Dan*_*ien 23

正如Patrick O'Hara所写,NuGet不会为您更改C++/CLI项目.请参阅GitHub问题NuGet/Home#1121 - 无法将托管包安装到CLI项目中.但是,使用NuGet命令行实用程序,NuGet.exe您可以让NuGet下载并解压缩所需的程序包.

有关完整示例,以下是我在Visual Studio 2013 C++/CLI项目中添加对OptimizedPriorityQueue 1.0.0 的引用的步骤:

  1. 如果尚未打开,请打开包管理器控制台(TOOLS> NuGet包管理器>包管理器控制台).
  2. 在程序包管理器控制台中,安装NuGet.CommandLine程序包:

    Install-Package NuGet.CommandLine
    

    (注意:在撰写本文时,NuGet.CommandLine的最新版本为2.8.6.对您而言可能有所不同.)

  3. 在项目文件夹中,现在应该有一个.nuget\packages.config包含以下内容的XML文件:

    <?xml version="1.0" encoding="utf-8"?>
    <packages>
      <package id="NuGet.CommandLine" version="2.8.6" />
    </packages>
    
    Run Code Online (Sandbox Code Playgroud)
  4. 在Notepad ++等文本编辑器中,为<package>所需的包添加元素.在这种情况下,我补充说:

    <package id="OptimizedPriorityQueue" version="1.0.0" />
    
    Run Code Online (Sandbox Code Playgroud)

    .. <packages>元素内.

  5. 打开命令提示符(我打开了VS2013开发人员命令提示符,但常规命令提示符应该有效.)

  6. cd 进入项目文件夹.
  7. 运行以下命令,如果不同,则更改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.
    
  8. 在Visual Studio中右键单击该项目,然后选择" 属性".在" 公共属性">"引用"下,单击" 添加新引用..."按钮.
  9. 选择左侧的" 浏览 ".在"添加引用"对话框的"确定"和"取消"按钮旁边,有一个" 浏览..."按钮.单击它以打开文件选择对话框.
  10. 导航到NuGet解压缩到packages项目文件夹子目录的DLL,然后单击" 添加"按钮.单击" 确定"关闭"添加引用"对话框.
  11. 您现在应该能够在C++/CLI项目中使用程序集:

    using namespace Priority_Queue;
    
    //...
    
    Run Code Online (Sandbox Code Playgroud)

  • 第 2 步给出了与问题中相同的错误。 (6认同)
  • @ daniel-trebbien,有关Visual Studio 2017中第8步到第10步的所有线索吗? (4认同)
  • @daniel-trebbien,您如何处理软件包更新? (2认同)

小智 6

正如在该端口的答案中所提到的(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
Run Code Online (Sandbox Code Playgroud)

请注意,命令行参数将一行分隔为一行,以便于阅读.我们还决定将NuGet检入我们的源代码控制,而不是.NuGet文件夹.目标是使我们可以更轻松地为各种环境设置构建机器(并非所有环境都使用Visual Studio).首次运行此命令后,必须手动将依赖项添加到C++/CLI项目中.
希望有所帮助.


buy*_*ush 6

实际上似乎有可能使用以下步骤(至少使用NuGet >= 2.5)来安装和使用C++/CLI项目自动引用"常规"NuGet包:

  1. 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>
    
    Run Code Online (Sandbox Code Playgroud)
  2. .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>
    
    Run Code Online (Sandbox Code Playgroud)

即使的NuGet不装配引用添加到C++/CLI的项目,但它仍然插入任何.props.targets由包提供的文件.步骤1中的自定义目标将添加对我们的打包组件的引用.

据我所知,这个解决方案的一个缺点是,以这种方式添加的引用不会显示在Commpon Properties/Framework and ReferencesC++/CLI项目的部分中.可能还有其他人,所以使用它需要您自担风险......