这是一个C#项目。我了解nuget会参考packages.config获取有关下载/提取软件包的信息。但是我注意到它为不同的.net平台下载了多个版本。例如,在packages.config中:
<package id="log4net" version="1.2.11" targetFramework="net461"/>
nuget将所有版本从net10下载到net40。此外,.csproj文件中指定的位置与物理位置中的位置不一致。
在上面的示例中,.csproj中的位置类似于:
src/packages/lognet.1.2.11/lib/log4net.dll
该dll的物理位置为:
src/packages/log4net1.2.11/lib/netXX-full/log4net.dll
XX可以是10到40,正如我之前所说的,下载并提取了多个版本的log4net。
由于不一致,该项目注定要失败,原因是未找到包错误。
我应该如何解决此问题?
仅供参考:几天前,我问了一个相关但又不同的问题。
C# project, compiler complaining missing reference to log4net
答案 0 :(得分:0)
“直接并指向重点”的答案:您不必担心。当您在项目中安装或升级软件包时,NuGet会告诉项目系统要放入csproj
中的内容。请注意,这与还原软件包不同。在packages.config项目中安装软件包意味着Visual Studio将同时修改packages.config文件和csproj文件。当您的计算机上没有nuget软件包时,当NuGet下载并解压缩nuget软件包时,这称为还原,而不是安装。在上一个问题中,您说过您克隆了其他人的存储库,并且试图使其构建。您可以问他们为什么/为什么csproj与nuget.org上的log4net软件包不匹配。或者在Visual Studio中,按ctrl-q进行搜索,键入“程序包管理器控制台”并选择它。初始化后,在“默认项目”下拉列表中选择错误的log4net参考的项目,然后键入Update-Package -reinstall
。这应该解决它。或者,您可以右键单击解决方案资源管理器中的项目,选择“管理NuGet软件包”,卸载log4net,然后再次安装。您还可以考虑使用migrating from packages.config to PackageReference,它没有packages.config所具有的提示路径问题。
冗长而详尽的答案:使用NuGet时,“版本”一词通常是指软件包版本,在本例中为1.2.11。查看package page on nuget.org,在版本历史记录下,我们可以看到其他版本,例如1.2.10、2.0.0、2.0.1直至2.0.8。除非您有多个项目各自引用该软件包的不同版本,否则NuGet不会下载多个版本。
.NET具有不同版本的运行时,其中一些版本与其他版本不兼容,但是这些版本称为目标框架Monikers(TFM),尽管不为Microsoft工作的人倾向于将它们称为目标框架或这样的东西。它与其他托管运行时或脚本语言(如Java,Python,PHP等)相似,但可能更复杂,因为过去创建了大量TFM,主要针对具有不同功能的不同移动设备。另外,Windows运行时分为3个“家族”,其中TFM向后兼容,但仅在同一个“家族”内。 Nuget Client has a complex mapping of compatible TFMs用于为您的项目选择NuGet软件包中最接近的兼容TFM。
一个包可能为不同的TFM包含多个dll的另一个原因是,它们希望在较新的TFM中使用较新的API,同时仍允许目标为较早的TFM的项目在不使用新API的情况下使用该包。例如,尽管net45,net46,net47和不久的net48都与net40兼容,但是net40没有异步等待。因此,一个程序包可能具有一个net40 dll,因此以net40为目标的项目仍可以使用该程序包,但是该程序包也可以包含带有额外异步API的net45 dll。 net1x,net 2x和net3x太旧了(net40和net45也是如此),软件包很少再为这些旧版本提供dll。但是,log4net 1.2.11于2011年发布,当时这些较旧的TFM可能仍然足够普遍,值得为其提供兼容性。
因此,您在log4net软件包的lib文件夹中看到的不是log4net的不同版本,它实际上是log4net的相同版本,但针对不同的TFM进行了编译。这样会增加可以使用该程序包的项目数量。
您正在使用的项目具有不存在的HintPath的原因有多种。鉴于您到目前为止提供的信息,这听起来像是有人手动编辑了csproj,还是有人创建了自己的log4net v1.2.11 nuget程序包,该程序包中的dll与nuget程序包中的dll位于不同的位置。 org。 NuGet软件包被设计为不可变的,这意味着从任何其他NuGet提要中下载具有特定软件包ID(名称)的nupkg,并且软件包版本应与具有相同软件包ID +版本的所有其他nupkg相同。如果不是这样,则与安装软件包的人相比,NuGet从其他来源还原软件包时,您会遇到构建错误。
最后,带有packages.config的NuGet不能手动编辑。您不应该自己编辑并将packages.config文件或“引用”或“ HintPath”保存在csproj中。使用NuGet程序包管理器UI或程序包管理器控制台来安装,卸载和升级程序包。 NuGet客户端中有很多逻辑,而不仅仅是资产选择,如果该软件包使用特定功能,您会出错。
在Visual Studio 2017中,NuGet添加了一种引用包的新方法,称为PackageReference。您可能需要转到工具->选项,找到NuGet软件包管理器->常规,然后更改默认的软件包管理格式或启用“允许在首次安装软件包时选择格式”。也可以右键单击许多项目类型,并可以选择迁移到PackageReference,但是尚未为所有项目类型(主要是ASP.NET)启用此选项。 PackageReference不支持packages.config支持的某些功能,并且某些项目类型也不支持PackageReference。但是在大多数情况下,它是受支持的,并且如果可以使用它,它具有多个优点,包括不再在csproj中放置提示路径以及避免当前遇到的特定问题(还原时,NuGet会写一个文件{ {1}}包含编译器使用的选定资产的路径,这意味着如果您更改源代码存储库结构,只需执行NuGet还原即可解决该问题,而使用packages.config您可能需要重新安装其中的每个软件包。每个项目)。使用.NET Core引入的新SDK样式的项目根本不支持packages.config,无论其值多少钱。
哇,我漫步的时间比我预期的要长得多。我希望它能帮助您不要迷惑您。