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

时间:2022-09-01 14:27:39

I have made a NuGet package that works well when I use it from a C# project. It contains a DLL in the lib/net40 directory, 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++,我如何修改我的包,以便在c++ /CLI项目中将DLL添加为托管引用?我找不到任何解释这个的教程。如果我尝试按原样添加包,会得到以下错误:

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/本机之下,但根据http://docs.nuget.org/docs/reference/supportfornative -projects,这是不受支持的。而且,仅仅将DLL直接放在lib下似乎没有任何作用。

Apparently, I am supposed to do this with a .props or .targets file under build/native, but what do I need to put into those files to make this work ?

显然,我应该在build/native下使用.props或.target文件来完成此工作,但是我需要将哪些文件放入这些文件中才能使其工作?

5 个解决方案

#1


17  

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 OptimizedPriorityQueue 1.0.0 in a Visual Studio 2013 C++/CLI project:

在一个完整的示例中,我在Visual Studio 2013 c++ /CLI项目中添加了一个引用,以优化priorityqueue 1.0.0:

  1. Open the Package Manager Console if not already open (TOOLS > NuGet Package Manager > Package Manager Console).
  2. 如果尚未打开,请打开包管理器控制台(工具> NuGet包管理器>包管理器控制台)。
  3. In the Package Manager Console, install the NuGet.CommandLine package:

    在包管理器控制台,安装NuGet。命令行包:

    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.)

    (注:本文为NuGet的最新版本)。命令行是2.8.6。你可能会不一样。

  4. Within your project folder, there should now be a .nuget\packages.config XML file with the following contents:

    在您的项目文件夹中,现在应该有一个.nuget\包。配置XML文件,内容如下:

    <?xml version="1.0" encoding="utf-8"?>
    <packages>
      <package id="NuGet.CommandLine" version="2.8.6" />
    </packages>
    
  5. In a text editor such as Notepad++, add a <package> element for the desired package. In this case, I added:

    在诸如Notepad++ +等文本编辑器中,为所需的包添加一个 元素。在这种情况下,我补充说:

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

    .. within the <packages> element.

    . .在 <包> 元素。

  6. Open a command prompt (I opened a VS2013 Developer Command Prompt, but a regular command prompt should work.)

    打开命令提示符(我打开了VS2013 Developer命令提示符,但是常规命令提示符应该可以工作)。

  7. cd into the project folder.
  8. cd进入项目文件夹。
  9. Run the following command, changing the version number of NuGet.CommandLine if different:

    运行以下命令,更改NuGet的版本号。如果不同的命令行:

    .\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.
    
  10. Right click on the project in Visual Studio and select Properties. Under Common Properties > References, click the Add New Reference… button.
  11. 在Visual Studio中右键单击项目并选择Properties。在常用属性>引用下,单击Add New Reference…按钮。
  12. Select Browse on 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.
  13. 选择左边的Browse。在Add Reference对话框的OK和Cancel按钮旁边,有一个Browse…按钮。单击它打开文件选择对话框。
  14. Navigate to the DLLs that NuGet unpacked to the packages subdirectory of your project folder and click the Add button. Click OK to close the Add Reference dialog.
  15. 导航到NuGet解压缩到项目文件夹的packages子目录的dll,并单击Add按钮。单击OK关闭添加引用对话框。
  16. You should now be able to use the assembly in your C++/CLI project:

    您现在应该能够在您的c++ /CLI项目中使用这个程序集:

    using namespace Priority_Queue;
    
    //...
    

#2


3  

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.

注意,命令行areguments被分隔为一行,以便于阅读。我们还决定在.NuGet文件夹下将NuGet检查到源代码控制中。我们的目标是使为我们的各种环境(不是所有环境都使用Visual Studio)设置构建机器变得更容易。第一次运行此命令后,必须手动将依赖项添加到c++ /CLI项目中。希望有帮助。

#3


3  

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项目中引用:

  1. Add (or modify) a build\<ProjectName>.targets file to your project to be packaged and put following content into it (make sure to replace <AssemblyName> with an actual value):

    添加(或修改)一个build\ 。将目标文件打包到您的项目中,并将以下内容放入其中(确保将 替换为实际值):

    <?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. In the .nuspec of the packaged project add one or more file entries to also place the assembly in lib\native\ directory at the target machine:

    在打包项目的.nuspec中添加一个或多个文件条目,还可以将程序集放在目标机器的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 .props and .targets files provided by a package. And the custom target from step 1 will add a reference to our packaged assembly.

即使NuGet不向c++ /CLI项目添加程序集引用,它仍然插入包提供的.props和.target文件。步骤1中的自定义目标将添加到我们的打包组装的引用。

One drawback of 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 References section of the C++/CLI project. There may also be others, so use it at your own risk...

在我看来,这种解决方案的一个缺点是,以这种方式添加的引用没有显示在c++ /CLI项目的Commpon属性/框架和引用部分。也可能有其他的,所以用它来承担你自己的风险……

#4


1  

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#项目,创建一个虚拟的c#项目

#5


-5  

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.

凭证实际上是通过添加包源的machinekey进行加密的。除非使用明文变体,否则setApiKey命令应该作为构建的一部分运行。

#1


17  

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 OptimizedPriorityQueue 1.0.0 in a Visual Studio 2013 C++/CLI project:

在一个完整的示例中,我在Visual Studio 2013 c++ /CLI项目中添加了一个引用,以优化priorityqueue 1.0.0:

  1. Open the Package Manager Console if not already open (TOOLS > NuGet Package Manager > Package Manager Console).
  2. 如果尚未打开,请打开包管理器控制台(工具> NuGet包管理器>包管理器控制台)。
  3. In the Package Manager Console, install the NuGet.CommandLine package:

    在包管理器控制台,安装NuGet。命令行包:

    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.)

    (注:本文为NuGet的最新版本)。命令行是2.8.6。你可能会不一样。

  4. Within your project folder, there should now be a .nuget\packages.config XML file with the following contents:

    在您的项目文件夹中,现在应该有一个.nuget\包。配置XML文件,内容如下:

    <?xml version="1.0" encoding="utf-8"?>
    <packages>
      <package id="NuGet.CommandLine" version="2.8.6" />
    </packages>
    
  5. In a text editor such as Notepad++, add a <package> element for the desired package. In this case, I added:

    在诸如Notepad++ +等文本编辑器中,为所需的包添加一个 元素。在这种情况下,我补充说:

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

    .. within the <packages> element.

    . .在 <包> 元素。

  6. Open a command prompt (I opened a VS2013 Developer Command Prompt, but a regular command prompt should work.)

    打开命令提示符(我打开了VS2013 Developer命令提示符,但是常规命令提示符应该可以工作)。

  7. cd into the project folder.
  8. cd进入项目文件夹。
  9. Run the following command, changing the version number of NuGet.CommandLine if different:

    运行以下命令,更改NuGet的版本号。如果不同的命令行:

    .\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.
    
  10. Right click on the project in Visual Studio and select Properties. Under Common Properties > References, click the Add New Reference… button.
  11. 在Visual Studio中右键单击项目并选择Properties。在常用属性>引用下,单击Add New Reference…按钮。
  12. Select Browse on 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.
  13. 选择左边的Browse。在Add Reference对话框的OK和Cancel按钮旁边,有一个Browse…按钮。单击它打开文件选择对话框。
  14. Navigate to the DLLs that NuGet unpacked to the packages subdirectory of your project folder and click the Add button. Click OK to close the Add Reference dialog.
  15. 导航到NuGet解压缩到项目文件夹的packages子目录的dll,并单击Add按钮。单击OK关闭添加引用对话框。
  16. You should now be able to use the assembly in your C++/CLI project:

    您现在应该能够在您的c++ /CLI项目中使用这个程序集:

    using namespace Priority_Queue;
    
    //...
    

#2


3  

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.

注意,命令行areguments被分隔为一行,以便于阅读。我们还决定在.NuGet文件夹下将NuGet检查到源代码控制中。我们的目标是使为我们的各种环境(不是所有环境都使用Visual Studio)设置构建机器变得更容易。第一次运行此命令后,必须手动将依赖项添加到c++ /CLI项目中。希望有帮助。

#3


3  

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项目中引用:

  1. Add (or modify) a build\<ProjectName>.targets file to your project to be packaged and put following content into it (make sure to replace <AssemblyName> with an actual value):

    添加(或修改)一个build\ 。将目标文件打包到您的项目中,并将以下内容放入其中(确保将 替换为实际值):

    <?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. In the .nuspec of the packaged project add one or more file entries to also place the assembly in lib\native\ directory at the target machine:

    在打包项目的.nuspec中添加一个或多个文件条目,还可以将程序集放在目标机器的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 .props and .targets files provided by a package. And the custom target from step 1 will add a reference to our packaged assembly.

即使NuGet不向c++ /CLI项目添加程序集引用,它仍然插入包提供的.props和.target文件。步骤1中的自定义目标将添加到我们的打包组装的引用。

One drawback of 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 References section of the C++/CLI project. There may also be others, so use it at your own risk...

在我看来,这种解决方案的一个缺点是,以这种方式添加的引用没有显示在c++ /CLI项目的Commpon属性/框架和引用部分。也可能有其他的,所以用它来承担你自己的风险……

#4


1  

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#项目,创建一个虚拟的c#项目

#5


-5  

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.

凭证实际上是通过添加包源的machinekey进行加密的。除非使用明文变体,否则setApiKey命令应该作为构建的一部分运行。