ChatGPT解决这个技术问题 Extra ChatGPT

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

当我从 C# 项目中使用它时,我制作了一个运行良好的 NuGet 包。它在 lib/net40 目录中包含一个 DLL,该 DLL 被添加为参考。

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

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

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

显然,我应该使用 build/native 下的 .props.targets 文件来执行此操作,但是我需要在这些文件中添加什么才能使其正常工作?

我认为这更像是 NuGet 中的一个错误,而不是你需要在包中调整的东西。看到这个:nuget.codeplex.com/workitem/3665另外,这个问题是相关的:stackoverflow.com/q/18786338/289770
谢谢!有趣的是,在我提出问题的第二天,错误报告是如何发布的。我现在已经投票了。尽管如此,无论有没有错误,我相信使用 NuGet 脚本可以解决这个问题,我正在寻找一个可以做到这一点的指南。
10 个月后,但也许这 ([stackoverflow.com/questions/23571241/…) 可能会对您有所帮助。 [1]:stackoverflow.com/questions/23571241/…

C
Community

作为 Patrick O'Hara wrote,NuGet 不会为您更改 C++/CLI 项目。见GitHub Issue NuGet/Home#1121 - Cannot install managed packages into a CLI project。但是,使用 NuGet 命令行实用程序 NuGet.exe,您可以让 NuGet 下载并解压缩所需的包。

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

如果尚未打开包管理器控制台,请打开(工具 > NuGet 包管理器 > 包管理器控制台)。在包管理器控制台中,安装 NuGet.CommandLine 包:Install-Package NuGet.CommandLine (注意:在撰写本文时,NuGet.CommandLine 的最新版本是 2.8.6。它可能对您有所不同。)在您的项目中文件夹,现在应该有一个 .nuget\packages.config XML 文件,其内容如下: 在 Notepad++ 等文本编辑器中,为所需的包添加 元素。在这种情况下,我在 元素中添加了: ..。打开命令提示符(我打开了 VS2013 开发人员命令提示符,但常规命令提示符应该可以工作。) cd 进入项目文件夹。运行以下命令,更改 NuGet.CommandLine 的版本号(如果不同): .\packages\NuGet.CommandLine.2.8.6\tools\NuGet.exe Install -NonInteractive -OutputDirectory packages .nuget\packages.config 对我来说,输出是:安装“OptimizedPriorityQueue 1.0.0.0”。成功安装“OptimizedPriorityQueue 1.0.0.0”。 packages.config 中列出的所有软件包都已安装。右键单击 Visual Studio 中的项目并选择属性。在 Common Properties > References 下,单击 Add New Reference... 按钮。选择左侧的浏览。在 Add Reference 对话框的 OK 和 Cancel 按钮旁边,有一个 Browse... 按钮。单击以打开文件选择对话框。导航到 NuGet 解压到项目文件夹的 packages 子目录的 DLL,然后单击“添加”按钮。单击“确定”关闭“添加引用”对话框。您现在应该能够在您的 C++/CLI 项目中使用该程序集: using namespace Priority_Queue; //...


@daniel-trebbien,您如何处理软件包更新?
@daniel-trebbien,任何线索如何在 Visual Studio 2017 中执行步骤 8 到 10?
这在 Visual Studio 2013 中对我来说非常有效。我更喜欢这个解决方案,而不是创建一个 C# 虚拟项目并将 dll 从一个项目复制到另一个项目。我能够添加 NLog 4.0.0。
很有帮助谢谢!仅供参考,当我在 VS 2019 中执行此操作时,我不得不稍微更改第 7 步命令,packages.config 是在项目的基本目录中创建的,而不是 .nuget 文件夹。此外,要在步骤 8 中将“浏览”作为选项查看,我必须确保我的项目已配置为“公共语言运行时支持 (/clr)”hth, X
第 2 步给了我与问题相同的错误。
s
swalex

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

将 build\.targets 文件添加(或修改)到要打包的项目中,并将以下内容放入其中(确保将 替换为实际值): $(MSBuildThisFileDirectory)..\lib\native\.dll 打包项目的.nuspec中添加一个或多个文件条目以将程序集也放置在目标计算机的 lib\native\ 目录中: ... ... < !-- 不要忘记包含引用的 .targets 文件 --> ...

即使 NuGet 不向 C++/CLI 项目添加程序集引用,它仍会插入包提供的任何 .props.targets 文件。步骤 1 中的自定义目标将添加对我们打包程序集的引用。

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


C
Community

如对此端口 (Nuget won't install Entity Framework into C++/CLI project) 的答复中所述,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

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


看起来如果我的 C++/CLI 项目是类库(程序集)而不是 exe,nuget 仍然失败。
@WeipengL 这是一个很老的问题。您的回复缺乏细节。也许您应该创建一个新问题来描述您的问题并参考这个问题?
C
Chandra

简单的解决方法是将此类 NuGet 包装在常规 .NET 项目 (C#) 中,并在 C++/CLI 项目中引用相同的内容。


M
Mikael

安装程序尝试在 C# 启动项目中添加对自身的引用。在安装之前将 C# 项目作为解决方案中的启动项目。如果没有,请创建一个虚拟 C# 项目


C# 与 C++/CLI 不同
J
John Foll

我的解决方案不会更容易为 Cli 项目添加 Nuget 包支持,但它允许我将 nuget 包添加到我的 Cli 包中。

我收到错误消息:“您正在尝试将此包安装到以 'native,Version=v0.0' 为目标的项目中,但该包不包含任何与该框架兼容的程序集引用或内容文件。”当我尝试安装 OptiPlot.WPF 或 NuGet.Commandline 时。

这可能不是满足每个人需求的完整解决方案,但它对我有用。我发现了一种将 OptiPlot.WPF 放入示例 C++.Net 项目的“作弊”方式。我的解决方案中有一个 C# 主程序项目 - 我在那里安装了包:Install-Package OxyPlot.Wpf -Version 2.0.0

然后我将 packages.config 文件和 packages 文件夹从那里复制到我的 C++ .Net 类库项目中。然后我编辑了packages.config文件,取出了一些不适用的东西,我可能在不需要的包中取出了一个包。然后我将 C++ .Net 类库项目中的引用添加到 packages/OxyPlot.Wpf.2.0.0 文件夹。

现在我可以在 C++ 中使用 OxyPlot!凉爽的!


Y
Yennefer

上面的答案存在二级依赖问题(至少在我的 Visual Studio 2019 上)。

为了解决这个问题,我通常创建一个空的 c# 控制台应用程序并引用那里的所有包。

然后,我使用此构建后代码段将项目主要工件以外的所有内容复制到解决方案文件夹中名为 packages 的公共存储中。

  <Target Name="PostBuild" AfterTargets="PostBuildEvent">
    <PropertyGroup>
      <SharedLibraries>$(SolutionDir)\packages</SharedLibraries>
    </PropertyGroup>

    <ItemGroup>
      <Artifacts Include="$(OutDir)\**" />
    </ItemGroup>

    <RemoveDir Condition=" Exists('$(SharedLibraries)')" Directories="$(SharedLibraries)" />
    <MakeDir Condition=" !Exists('$(SharedLibraries)')" Directories="$(SharedLibraries)" />

    <Copy SourceFiles="@(Artifacts)" DestinationFolder="$(SharedLibraries)\%(RecursiveDir)" />

    <ItemGroup>
      <ExtraFiles Include="$(SharedLibraries)\$(ProjectName).*"></ExtraFiles>
    </ItemGroup>

    <Delete Files="@(ExtraFiles)" />

  </Target>

然后使用 c++/cli 项目中的自定义任务部署整个 packages 文件夹。

如果引用的包以 AnyCPU 为目标,则此解决方案适用,否则需要进行一些修改才能为每个处理器体系结构使用不同的文件夹,并且可能无法正常工作。

此解决方案并不优雅,但解决了从 c++/cli 项目可靠地使用 nuget 包(间接)的目的。

此解决方案相对于此处发布的其他解决方案的优点是路径没有版本控制,因此在正常包升级期间不会更改 c++/cli 项目。


O
Omar H

凭据实际上是使用添加包源的机器密钥加密的。除非使用明文变体,否则 setApiKey 命令可能应该作为构建的一部分运行。