【问题标题】:Add a package with a local package file in 'dotnet'在 'dotnet' 中添加带有本地包文件的包
【发布时间】:2023-04-03 04:51:01
【问题描述】:

使用dotnet 命令行工具,如何添加对通过 NuGet 下载的现有本地包的引用?

我尝试使用dotnet 将本地包添加到项目bar

dotnet add package /Users/sakra/foo/bin/Debug/foo.1.0.0.nupkg

foo.1.0.0.nupkg 是在另一个项目中使用dotnet pack 创建的。但是,dotnet add package 命令会尝试从https://api.nuget.org/ 下载文件foo.1.0.0.nupkg,这当然会失败。

【问题讨论】:

    标签: c# nuget .net-core


    【解决方案1】:

    没有办法直接安装单个.nupkg 包。 NuGet 只能从提要安装和恢复,因此您需要将包所在的目录添加为提要。

    为此,添加一个NuGet.Config 文件,该文件将目录的位置添加为提要,因此您不必将源参数添加到每个NuGet 相关命令(尤其是dotnet restore):

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <packageSources>
        <add key="local-packages" value="../foo/bin/Debug" />
      </packageSources>
    </configuration>
    

    或者在 .NET Core 2.0 工具/NuGet 4.3.0 中,您还可以将源直接添加到应该使用 NuGet 提要的 .csproj 文件中:

    <PropertyGroup>
      <RestoreSources>$(RestoreSources);../foo/bin/Debug;https://api.nuget.org/v3/index.json</RestoreSources>
    </PropertyGroup>
    

    这将使所有命令都能够使用该包:

    • dotnet add package foo(可选添加-v 1.0.0
    • dotnet restore
    • dotnet run

    dotnet add package foo 将向*.csproj 添加一个包引用(此处假设为版本1.0.0):

    <ItemGroup>
    +    <PackageReference Include="foo" Version="1.0.0" />
    </ItemGroup>
    

    请注意,在开发过程中,如果您更改了 NuGet 包,但在生成 .nupkg 文件的项目和使用它的项目中都没有增加其版本,则需要清除本地包缓存在再次恢复之前:

    dotnet nuget locals all --clear
    dotnet restore
    

    我在https://github.com/dasMulli/LocalNupkgExample创建了一个小示例项目

    【讨论】:

    • 这对我不起作用。 ..foo/bin/Debug 不包含 nuspec 文件,我得到的只是错误“与项目中的“所有”框架不兼容”。我真的认为使用随机文件夹作为包源不再适用于 nuget 4(如果曾经这样做的话)。
    • 您的 nupkg 是否按照惯例命名? my.pkg.1.0.0.nupkg?这对于 nuget 为包源构建元数据也至关重要。
    • 我在github.com/dasMulli/LocalNupkgExample 创建了一个小示例项目,您可以使用./run-example.sh 运行它
    • 我注意到在您的示例中,您在 csproj 文件中有 both 一个 Nuget.config 文件 一个 RestoreSources 块。在您的讨论中,您提到 RestoreSources 是 Nuget.config 文件的替代品。 RestoreSources 块是否要与 Nuget.config 文件一起使用?
    • @melston,因为我希望用它们之间的文本来说明,它们是可供选择的替代方案,但 csproj 的 RestoreSources 功能仅适用于即将发布的 @ 2.0 版本987654341@ CLI 和 VS 2017 15.3 更新(目前都在预发布中)
    【解决方案2】:

    我在这方面苦苦挣扎了很多,这是我让它发挥作用的唯一方法:

    • 创建一个新的“包源”来使用

    • 将 .nupkg 文件安装到包源中,使用 nuget add ...

    • 使用dotnet add package Foo -s ... 安装包。

    具体来说,需要用到的命令有:

    nuget add ../whatever/lib/MyPackage.1.0.0.nupkg -Source ./packages

    还有:

    dotnet 添加包 MyPackage -s ./packages

    注意具体,这里有几点:

    • 首先,您不能简单地将 .nupkg 文件复制到包文件夹中。我已经尝试了很多这样的变体,我只能说它不适用于我,在 Windows、Mac 或 Linux 上。

    • 必须使用至少为 3 的 NuGet 版本,否则这不起作用。 在撰写本文时,.NET Core 的默认版本是 2.xx。您需要手动升级 NuGet。

    • 您在 .csproj 文件中的引用将如下所示:

    ... PackageReference Include="SolidMud" Version="1.0.0" ...

    即,特别注意它没有在依赖信息中引用您的包源;只是包名和版本。

    基本上,这意味着如果您运行dotnet restore,除非包被缓存在该机器上的全局 NuGet 缓存中,否则它将无法工作;第一次恢复时需要运行dotnet restore -s ./packages

    正如另一个答案中提到的,包是全局缓存的;如果要滚动到具有相同版本 id 的新版本,则需要使用dotnet nuget locals all --clear 或手动删除缓存的包版本。

    以下是将名为“SolidMud”的 .nupkg 恢复到全新的 .NET Core 控制台应用程序的具体完整示例:

    $ dotnet new console -n TestPkgs
    The template "Console Application" was created successfully.
    
    Processing post-creation actions...
    Running 'dotnet restore' on TestPkgs/TestPkgs.csproj...
    Restore succeeded.
    
    $ cd TestPkgs/
    $ mkdir packages
    $ nuget add ../core-solidmud/lib/SolidMud.1.0.0.nupkg -Source ./packages
    Installing SolidMud 1.0.0.
    Successfully added package '../core-solidmud/lib/SolidMud.1.0.0.nupkg' to feed './packages'.
    
    $ dotnet add package SolidMud -s ./packages
    Microsoft (R) Build Engine version 15.3.117.23532
    Copyright (C) Microsoft Corporation. All rights reserved.
    
    Writing /var/folders/29/0695l4fj26j64kp4p8vwqq5h0000gn/T/tmpkRBaST.tmp
    info : Adding PackageReference for package 'SolidMud' into project '/Users/doug/dev/dotnet-packages/TestPkgs/TestPkgs.csproj'.
    log  : Restoring packages for /Users/doug/dev/dotnet-packages/TestPkgs/TestPkgs.csproj...
    info : Package 'SolidMud' is compatible with all the specified frameworks in project '/Users/doug/dev/dotnet-packages/TestPkgs/TestPkgs.csproj'.
    info : PackageReference for package 'SolidMud' version '1.0.0' added to file '/Users/doug/dev/dotnet-packages/TestPkgs/TestPkgs.csproj'.
    

    【讨论】:

    • 我不确定如何创建 .nupkg 文件?
    • @KevinBurton 创建 nuget 包本身就是一个完整的主题。如果您使用的是 .Net core 或最新版本的 nuget,请参阅 docs.microsoft.com/en-us/dotnet/core/tools/…;你基本上可以只使用dotnet packnuget pack Foo.csproj;如果您使用的是完整的 .Net,这样做会更加痛苦,您必须四处寻找细节。
    【解决方案3】:

    使用-s|--source option 指定包的位置文件夹。例如:

    dotnet add package Microsoft.AspNetCore.Cors -s "d:\Cache\localfeed" -f netcoreapp1.1
    

    更新:感谢MartinUllrich's answer:您不能简单地安装.nupkg 文件。在安装软件包之前,必须指定 local feed 并将本地 .nupkg 文件添加到提要中。详情请查看MartinUllrich's answer

    很遗憾,您可能会遇到这个阻塞问题:

    Package 'NameOfPackage' is incompatible with 'all' frameworks in project

    此时它是打开的,我能够在稳定的软件包版本上重现它。

    【讨论】:

    • 这并不能回答问题:您描述的是获取 nupkg 已经在 nuget 存储库中 并安装它;问题是,只有一个 foo.1.0.0.nupkg 你如何安装它。
    • @Doug 你如何看待-v|--version 选项来指定确切的包版本?是的,安装软件包不需要本地提要。我在回答中提供了更多详细信息。
    • 我得到了同样的错误(与所有框架不兼容),但这似乎是“找不到包”的一般错误。例如,尝试dotnet add package ADFADFDFVCXVZD -s .... 仍然会出现相同的错误。我不认为这是一个框架问题。我认为它只是找不到 nupkg 文件。 IE。我认为这行不通。
    • @Doug 尝试从 VS 离线提要安装一个包:C:\Program Files (x86)\Microsoft SDKs\NuGetPackages 在我的情况下它工作正常,所以我相信这个错误在 dotnet pack 命令中。
    • 顺便说一句,在 90% 的时间里我都看到了 incompatible with 'all' 消息,这是因为包名称不正确或者已经存在 foolib 等 nuget 包nuget.org.
    【解决方案4】:

    在 .NET Core 3.1 (Arm64) 中,我可以通过添加本地源和包

    dotnet nuget add source ~/my/nuget-packages/
    mv mypackage.1.1.1.nuget ~/my/nuget-packages/
    dotnet add package mypackage
    

    并且~/.nuget/NuGet/NuGet.Config 已更改。

    【讨论】:

      【解决方案5】:

      我想我会把这个 Dockerfile 放在这里,以防有人想要一个额外的例子。我的私有/本地 nuget 包存在于 ./packages 目录中,其中包含所有必要的 *.nupkg 文件

      FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS base
      
      RUN apt-get update && apt-get install -y gcc-multilib && apt-get install -y libcurl3-gnutls
      WORKDIR /app
      EXPOSE 2275
      EXPOSE 44303
      
      FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
      WORKDIR /src
      
      COPY . .
      WORKDIR /src/SampleWebApp
      RUN dotnet nuget add source /src/packages
      RUN dotnet restore
      RUN dotnet build -c Release -o /app
      
      FROM build AS publish
      RUN dotnet publish -c Release -o /app
      
      FROM base AS final
      WORKDIR /app
      COPY --from=publish /app .
      
      EXPOSE 80
      ENTRYPOINT ["dotnet", "SampleWebApp.dll"]
      

      【讨论】:

        【解决方案6】:

        这不是您问题的直接答案,但我猜您想使用本地提要中的软件包的原因是出于开发目的,因此它可能对您和其他人仍然非常相关。

        有一个项目试图做npm link 类似的体验,称为NuLink。它实质上创建了从缓存的 nuget 包到包 bin/Debug 文件夹的符号链接。使用本地提要会有更好的体验。

        我对安装 3d 派对 .exe 文件有点谨慎,所以我使用了 NuLink 中使用的简单版本的方法,不需要任何 3d 派对工具:

        1. 安装旧版本的软件包(例如 1.0.0)。您可以在使用项目中引用它并运行 dotnet restore 例如
        2. 从已安装的包中重命名/删除lib 文件夹。 Windows 示例:rename C:\Users\&lt;USERNAME&gt;\.nuget\packages\MyPackage\1.0.0\lib lib_old
        3. 从它创建一个符号链接/连接到您的包调试文件夹。在 Windows 上会是这样的:mklink /J C:\Users\&lt;USERNAME&gt;\.nuget\packages\MyPackage\1.0.0\lib C:\Source\MyPackage\bin\Debug
        4. 在您使用的项目中将包的“降级”到 1.0.0 版

        现在,只要您使用 1.0.0,您的使用项目就应该使用您的包中的 .dll/.pdb 文件引用该文件夹。您只需构建您的包,然后它应该立即可用,包括导航到文件和调试(因为 .pdb 文件位于同一文件夹中)。

        附:根据您使用的 dotnet/nuget 版本,可能会有很多调整,但要点应该仍然相同,只是文件夹结构有所不同。

        【讨论】:

          猜你喜欢
          • 2017-08-05
          • 1970-01-01
          • 2013-08-27
          • 1970-01-01
          • 2016-11-04
          • 1970-01-01
          • 2011-10-13
          • 2016-12-26
          • 2021-08-10
          相关资源
          最近更新 更多