为什么在编译时,我的C#项目的构建会产生以下输出?
在我的电脑上,我安装了DevExpress。我对我的应用程序做了一些修改,现在似乎在编译我的C#项目时,它一直在搜索与DevExpress相关的NuGet包,似乎并没有停止。
在我的构建日志中,出现了以下几行(数字是后续为便于引用而添加的):
12:01:57:647 NuGet Config files used:
12:01:57:647 (1) C:\\Development\\workarea\\\<Solution_Dir\>\\NuGet.Config
12:01:57:647 (2) C:\\Development\\workarea\\\<General_Dir\>\\NuGet.Config
12:01:57:647 (3) C:\\Users\\DDESCA\\AppData\\Roaming\\NuGet\\NuGet.Config
12:01:57:647 (4) C:\\Program Files (x86)\\NuGet\\Config\\DevExpress 24.2.config
12:01:57:647 (5) C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config
12:01:57:647 (6) C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config
我让AI帮忙,它让我去解决方案目录中的NuGet.Config文件,并添加以下标签:
<packageSourceMapping>
<packageSource key="OwnNugetPackagesFeed">
<package pattern="Own.\*" />
</packageSource>
<packageSource key="nuget.org">
<package pattern="\*" />
</packageSource>
</packageSourceMapping>
<disabledPackageSources>
<add key="DevExpress 24.2 Local" value="true" />
<add key="DevExpress_24.2" value="true" />
</disabledPackageSources>
我照做了,但提到的那一行又出现在输出日志中。(我并没有重新构建整个解决方案,只是重新构建相应的项目。)
有没有人知道如何在构建输出日志中去掉那个DevExpress参考项?我的应用程序从哪里获取NuGet配置文件的列表?
一些见解:
与此同时,我开始了解NuGet是从哪些位置获取配置(大致如下):
- 在
C:\Program Files (x86)\NuGet\Config\中(解释 (4)、(5) 和 (6)) - 在
C:\Users\...\AppData\Roaming\Nuget中(解释 (3)) - 在解决方案目录中(解释 (1))
有谁能解释一下为什么使用引用(2)吗?(供你参考:这并不是项目目录。)
解决方案
你在这里混淆了两件事:NuGet配置文件 *.Config 和NuGet包源(也称为sources)。
你想要的是什么——配置文件
Multiple
NuGet.Config文件允许你将设置存放在不同的位置,从而应用于单个解决方案,或一组解决方案。这些设置共同应用于从命令行或Visual Studio启动的任何NuGet操作[...]
具体来说,当命令行未显式指定配置文件时,NuGet会按以下顺序从不同的配置文件加载设置:
- (较少见)
NuGetDefaults.Config文件,其中仅包含与包源相关的设置。- 计算机级文件。 [
%ProgramFiles(x86)%\NuGet\Config]- 用户级文件。 [
%appdata%\NuGet\NuGet.Config]- 从驱动器根到当前文件夹的路径中每个文件夹里找到的文件(在其中调用
nuget.exe的位置,或包含Visual Studio解决方案的文件夹)。例如,如果在c:\A\B\C中调用命令,NuGet会在c:\、然后c:\A、再到c:\A\B,最终到c:\A\B\C。
在安装DevExpress过程中,会创建 C:\\Program Files (x86)\\NuGet\\Config\\DevExpress 24.2.config。这使得在任何项目中使用DevExpress变得方便,因为它的NuGet配置始终被包含在内。
一个天真但可行的解决方案是删除该文件,或将其移动到不属于搜索层级的其他文件夹中。然而,这样你就需要对每个使用DevExpress的项目显式添加该配置。
你需要的是什么——包源
由于对 *.Config 文件的聚合,删除其中一个会有点棘手,否则会让其他项目的配置变得更复杂。
相反,简单地接受 C:\\Program Files (x86)\\NuGet\\Config\\DevExpress 24.2.config 一直被包含,就像 C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config 一样,即使某个项目可能不需要它们所做的任何事情。
通常,*.Config 在全局上下文中“有问题”的只是它会添加 包源。现在可能有几十个聚合的 *.Config 文件,每个文件都可能添加几十个源,需检查的源总数可能会变得非常长。在一个不使用DevExpress的项目中,你可能会问自己:”为什么要浪费时间去找DevExpress NuGet源中的每个包,即使该项目并不使用该源中的任何东西?“
与其试图删除 *.Config 文件,不如在项目级别限制NuGet源被评估的范围。有多种方法可以做到。
<clear /> 👎
你可以将这段添加到任意 *.Config 中,实质性地“打断”聚合导入的链条。这是一个极端选项,会移除 DevExpress 24.2.config,但也会连同之前在层级中定义的其他内容一起移除,如 Microsoft.VisualStudio.Offline.config。如果在计算机级文件夹 %ProgramFiles(x86)%\NuGet\Config 还有其他 *.Config 文件,那些也会被排除。这个选项与把 DevExpress 24.2.config 移动到其他位置的缺点类似。
禁用DevExpress源 👍
这就是AI建议你做的:
<disabledPackageSources>
<add key="DevExpress 24.2 Local" value="true" />
<add key="DevExpress_24.2" value="true" />
</disabledPackageSources>
我照做了,但提到的那一行又出现在输出日志中。
希望能在本答复中说明,你的期望有些混乱:当你移除通过 DevExpress 24.2.config 添加的包源时,并不意味着配置文件 DevExpress 24.2.config 本身不再被考虑。删除配置文件本身其实并不必要。
要验证所建议的代码段是否有效,请使用 dotnet nuget list source 来列出所有包源,或尝试还原一个DevExpress包,应该会失败。
这种方案的问题在于你必须将其显式添加到每一个不使用DevExpress的项目中。
包源映射 🚀
没有妥协的解决方案是让 DevExpress 24.2.config 在默认情况下始终包含,方便需要它的项目,同时在不需要它的项目中忽略它所添加的NuGet源。
这个解决方案以 Package Source Mapping 的形式出现。
通过包源映射,你可以按包筛选NuGet将搜索的源。
这也是AI给出的提示:
<packageSourceMapping>
<packageSource key="OwnNugetPackagesFeed">
<package pattern="Own.\*" />
</packageSource>
<packageSource key="nuget.org">
<package pattern="\*" />
</packageSource>
</packageSourceMapping>
你应该能够通过如下方式将DevExpress源仅限于在DevExpress包时被搜索:
<packageSourceMapping>
<packageSource key="DevExpress 24.2 Local">
<package pattern="DevExpress.*" />
</packageSource>
</packageSourceMapping>
我本身也不是DevExpress的用户,建议你查看 DevExpress 24.2.config 的文件内容,因为它可能已经为你做了这件事,这意味着你根本不需要执行任何操作。