简体   繁体   English

Visual Studio/nuget 如何决定要下载/精确的软件包版本?

[英]How does visual studio/nuget decides what version(s) of the package to download/exact?

This is a C# project.这是一个 C# 项目。 I understand that nuget consults packages.config for the info to download/extract packages.我知道 nuget 会咨询 packages.config 以获取下载/提取软件包的信息。 However I noticed that it downloaded multiple versions for different .net platforms.但是我注意到它为不同的 .net 平台下载了多个版本。 For example, in the packages.config:例如,在packages.config 中:

<package id="log4net" version="1.2.11" targetFramework="net461"/>

nuget downloads all the versions from net10 to net40. nuget 下载从 net10 到 net40 的所有版本。 In addition, the location specified in the .csproj file is not consistent to that in the physical location.此外,.csproj 文件中指定的位置与物理位置中的位置不一致。

In the above example, the location in the .csproj is something like:在上面的示例中,.csproj 中的位置类似于:

src/packages/lognet.1.2.11/lib/log4net.dll

the physical location for the dll is, however:但是,dll 的物理位置是:

src/packages/log4net1.2.11/lib/netXX-full/log4net.dll

XX can be from 10 to 40, as I said earlier, multiple versions of log4net were downloaded and extracted. XX可以是10到40,前面说了,log4net下载解压了多个版本。

Due to the inconsistency, the project is doomed to fail, citing package not found error.由于不一致,项目注定失败,引用包未找到错误。

How should I do to fix this problem?我该怎么做才能解决这个问题?

FYI: I asked a relevant but different question a few days ago.仅供参考:几天前我问了一个相关但不同的问题。

C# project, compiler complaining missing reference to log4net C# 项目,编译器抱怨缺少对 log4net 的引用

"direct and to the point" Answer : you shouldn't need to worry about it. “直截了当” 回答:您不必担心。 When you install or upgrade a package in a project, NuGet tells the project system what to put in the csproj .在项目中安装或升级包时,NuGet 会告诉项目系统在csproj放入什么。 Note that this is not the same thing as restoring packages.请注意,这与恢复软件包不同。 Installing packages in a packages.config project means Visual Studio will modify both the packages.config file and the csproj file.在packages.config 项目中安装包意味着Visual Studio 将同时修改packages.config 文件和csproj 文件。 When you don't have the nuget package on your machine, when NuGet downloads and extracts it, it's called a restore, not an install.如果您的计算机上没有 nuget 包,当 NuGet 下载并解压缩它时,这称为还原,而不是安装。 In the previous question you said that you cloned someone else's repo and you're trying to get it to build.在上一个问题中,您说您克隆了其他人的存储库,并且正在尝试构建它。 You could ask them how/why the csproj doesn't match the log4net package on nuget.org.您可以询问他们如何/为什么 csproj 与 nuget.org 上的 log4net 包不匹配。 Or in Visual Studio, press ctrl-q to go to search, type "package manager console" and select it.或者在 Visual Studio 中,按 ctrl-q 去搜索,输入“包管理器控制台”并选择它。 Once it's initialised, select the project with the bad log4net reference in the "default project" dropdown, then type Update-Package -reinstall .初始化后,在“默认项目”下拉列表中选择具有错误 log4net 引用的项目,然后键入Update-Package -reinstall This should fix it.这应该解决它。 Alternatively you can right click the project in Solution Explorer, select Manage NuGet Packages, uninstall log4net then install it again.或者,您可以右键单击解决方案资源管理器中的项目,选择管理 NuGet 包,卸载 log4net,然后重新安装。 You could also consider migrating from packages.config to PackageReference , which doesn't have this hint path problem that packages.config has.您还可以考虑从 packages.config 迁移到 PackageReference ,它没有 packages.config 具有的提示路径问题。

long, detailed answer : when using NuGet, the word "version" usually refers to the package version, in this case 1.2.11.长而详细的答案:使用 NuGet 时,“版本”一词通常指的是包版本,在本例中为 1.2.11。 Looking at the package page on nuget.org , under version history we can see other versions like 1.2.10, 2.0.0, 2.0.1 right up to 2.0.8.查看nuget.org上的包页面,在版本历史记录下,我们可以看到其他版本,如1.2.10、2.0.0、2.0.1到 2.0.8。 Unless you have multiple projects that each reference a different version of the package, NuGet did not download multiple versions.除非您有多个项目,每个项目都引用不同版本的包,否则 NuGet 不会下载多个版本。

.NET has different versions of the runtime, some of which are not compatible with others, but these are called Target Framework Monikers (TFM), although people who don't work for Microsoft tend just to call them the target framework or something like that. .NET 有不同版本的运行时,其中一些与其他版本不兼容,但这些称为目标框架名称 (TFM),尽管不为 Microsoft 工作的人倾向于将它们称为目标框架或类似名称. It's similar to other managed runtimes or scripting languages like Java, Python, PHP, and so on, but possibly more complex because a huge number of TFMs were created in the past, mainly for different mobile devices that had different capabilities.它类似于 Java、Python、PHP 等其他托管运行时或脚本语言,但可能更复杂,因为过去创建了大量 TFM,主要用于具有不同功能的不同移动设备。 Plus the Windows runtime is split into 3 "families" where TFMs are backwards compatible, but only within the same "family".此外,Windows 运行时分为 3 个“系列”,其中 TFM 向后兼容,但仅在同一个“系列”内。 The Nuget Client has a complex mapping of compatible TFMs that it uses to select the closest compatible TFM in the NuGet package for your project. Nuget Client 具有兼容 TFM 的复杂映射,它用于为您的项目选择 NuGet 包中最接近的兼容 TFM。

Another reason why a package might contain multiple dlls for different TFMs is because they want to use newer APIs in newer TFMs, while still allowing projects targeting an older TFM to use the package without the new APIs.一个包可能包含不同 TFM 的多个 dll 的另一个原因是因为他们希望在较新的 TFM 中使用较新的 API,同时仍然允许面向较旧 TFM 的项目使用没有新 API 的包。 For example, although net45, net46, net47 and soon net48 are all compatible with net40, net40 didn't have async-await.例如,虽然 net45、net46、net47 和很快的 net48 都与 net40 兼容,但 net40 没有 async-await。 So, a package might have a net40 dll so projects targeting net40 can still use the package, but the package can also contain a net45 dll with extra async APIs.因此,一个包可能有一个 net40 dll,因此面向 net40 的项目仍然可以使用该包,但该包也可以包含一个带有额外异步 API 的 net45 dll。 net1x, net 2x and net3x are so old, (as is net40 and net45) that packages rarely provide dlls for these old versions any more. net1x、net 2x 和 net3x 太旧了(net40 和 net45 也是如此),以至于软件包很少再为这些旧版本提供 dll。 However, log4net 1.2.11 was released in 2011, when these older TFMs were probably still common enough that it was worth providing compatibility for.然而,log4net 1.2.11 是在 2011 年发布的,当时这些较旧的 TFM 可能仍然很常见,值得提供兼容性。

So, what you see in the lib folder of the log4net package isn't different versions of log4net, it's actually the same version of log4net but compiled for different TFMs.所以,你在 log4net 包的 lib 文件夹中看到的不是不同版本的 log4net,它实际上是相同版本的 log4net,但为不同的 TFM 编译。 This increases the number of projects that can use the package.这增加了可以使用包的项目数量。

There are several possibilities why the project you're using has a HintPath that doesn't exist.您正在使用的项目具有不存在的 HintPath 的原因有多种。 Given the information information you've provided so far, it sounds like either someone manually edited the csproj, or someone created their own log4net v1.2.11 nuget package which had the dll in a different location within the nupkg compared to the package on nuget.org.鉴于您到目前为止提供的信息信息,听起来像是有人手动编辑了 csproj,或者有人创建了自己的 log4net v1.2.11 nuget 包,与 nuget 上的包相比,该包在 nupkg 中的不同位置具有 dll。组织。 NuGet packages are designed to be immutable meaning downloading a nupkg with a specific package id (name) and package version should be identical to all other nupkgs with the same package id + version from any other NuGet feed. NuGet 包被设计为不可变的,这意味着下载具有特定包 ID(名称)和包版本的 nupkg 应与来自任何其他 NuGet 提要的具有相同包 ID + 版本的所有其他 nupkg 相同。 When it's not, you can get build errors when NuGet restores the package from a different source compared to the person who installed the package.如果不是,当 NuGet 从与安装包的人不同的源还原包时,您可能会遇到构建错误。

Finally, NuGet with packages.config is not designed to be edited manually.最后,带有packages.config 的NuGet 不是为手动编辑而设计的。 You should not edit and save the packages.config file or the References or HintPath in the csproj yourself.您不应自己编辑和保存 csproj 中的 packages.config 文件或 References 或 HintPath。 Use the NuGet Package Manager UI or Package Manager Console to install, uninstall and upgrade packages.使用 NuGet 包管理器 UI 或包管理器控制台来安装、卸载和升级包。 There's a lot of logic in the NuGet client, not just asset selection, that you will get wrong if the package uses specific features. NuGet 客户端中有很多逻辑,不仅仅是资产选择,如果包使用特定功能,您会出错。

In Visual Studio 2017, NuGet added a new way to reference packages, called PackageReference.在 Visual Studio 2017 中,NuGet 添加了一种引用包的新方法,称为 PackageReference。 You may need to go to Tools->Options, find NuGet Package Manager->General and either change the default package management format or enable "allow format selection on first package install".您可能需要转到“工具”->“选项”,找到 NuGet 包管理器->“常规”,然后更改默认包管理格式或启用“首次安装包时允许格式选择”。 It should also be possible to right click many project types and have an option to migrate to PackageReference, but this hasn't been enabled for all project types (mainly ASP.NET).还应该可以右键单击许多项目类型,并可以选择迁移到 PackageReference,但尚未为所有项目类型(主要是 ASP.NET)启用此功能。 PackageReference does not support some features that packages.config supports, and some project types don't support PackageReference either. PackageReference 不支持packages.config 支持的某些功能,某些项目类型也不支持PackageReference。 But in the most common cases it is supported, and if you can use it, it has several advantages, including no longer putting a hint path in your csproj and avoiding the specific problem you're currently having (on restore NuGet writes a file obj\\project.assets.json which contains the paths to the selected assets, which the compiler uses, meaning if you change your source code repository structure, simply doing a NuGet restore will fix it, whereas with packages.config you may need to reinstall every package in every project).但是在最常见的情况下它是受支持的,如果你可以使用它,它有几个优点,包括不再在你的 csproj 中放置一个提示路径和避免你当前遇到的特定问题(在还原时 NuGet 写入一个文件obj\\project.assets.json包含编译器使用的所选资产的路径,这意味着如果您更改源代码存储库结构,只需执行 NuGet 还原即可修复它,而使用 packages.config 您可能需要重新安装每个在每个项目中打包)。 Projects using the new SDK style that was introduced with .NET Core don't support packages.config at all, for whatever that's worth.使用随 .NET Core 引入的新 SDK 样式的项目根本不支持 packages.config,无论值多少钱。

wow, I rambled for much longer than I expected I would.哇,我漫步的时间比我预期的要长得多。 I hope it helped more than confused you.我希望它对您有所帮助而不是让您感到困惑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何下载没有 nuget.exe 或 Visual Studio 扩展的 Nuget 包? - How to download a Nuget package without nuget.exe or Visual Studio extension? 如何下载Nuget包 - How to download Nuget package .NET / Visual Studio:如何查找给定包的NuGet包源 - .NET/Visual Studio: How to find NuGet Package Source for a given Package Visual Studio NuGet:为什么依赖包的.targets文件没有执行? - Visual Studio NuGet: Why dependent package's .targets file is not executed? Visual Studio Nuget无法安装任何软件包 - Visual Studio Nuget unable to install any package 使用nuget程序包自动配置VSIX的Visual Studio - configure visual studio with nuget package, VSIX automatically 从Visual Studio外部安装NuGet包 - Installing NuGet package from outside of Visual Studio Visual Studio 2017 中的 Nuget package 错误 - Nuget package error in Visual Studio 2017 有没有办法像 Visual Studio 那样“安装”nuget package,但是在部署服务器上 - Is there a way to "install" nuget package like the way Visual Studio does, but on a deployment server Visual Studio 2013 NuGet包还原在命令行中不起作用(不是msbuild而是vcvarsall.bat) - Visual Studio 2013 NuGet package restore does not work from command line (not msbuild but vcvarsall.bat)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM