Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >csproj 文件中那个空的 NuGetPackageImportStamp 是干什么的?

csproj 文件中那个空的 NuGetPackageImportStamp 是干什么的?

作者头像
walterlv
发布于 2023-10-22 01:54:50
发布于 2023-10-22 01:54:50
4210
举报

当我们在传统格式的 csproj 项目文件中安装 NuGet 包后,有时会在项目文件中发现空的 NuGetPackageImportStamp 节点。这个空的节点让我们这波强迫症患者觉得有点难以接受,关键是手工删除之后也没发现有什么副作用。

那么为什么会出现这个节点?它究竟有什么作用?


空的 NuGetPackageImportStamp 节点

NuGetPackageImportStamp 节点只会出现在传统的 csproj 文件中。如果你不清楚我这里指的传统的和新的 csproj 文件格式,那么可以阅读我的另一篇文章来了了解它们的区别:将 WPF、UWP 以及其他各种类型的旧 csproj 迁移成 Sdk 风格的 csproj

简单说来,在 Project 根节点中可以指定 Sdk 特性的 csproj 文件格式是新的 csproj 格式。由于 Sdk 特性的存在,使得很多的项目文件的功能得以有一个默认的实现。

而传统的 csproj 由于没有指定 Sdk 特性,所以很多的特性如果需要执行,需要先 Import 到 csproj 中,或者不断地修改 csproj 文件的内容以添加新的功能。

空的 NuGetPackageImportStamp 节点只会出现在传统的 csproj 文件中。如果你使用新格式的 csproj 文件,那么无论你如何安装 NuGet 包,都是不会看到 NuGetPackageImportStamp 节点出现的。

NuGetPackageImportStamp 在传统 csproj 文件中是这样的:

1 2 3 4 5 6 7

<?xml version="1.0" encoding="utf-8"?><br> <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"><br> <PropertyGroup><br>++ <NuGetPackageImportStamp><br>++ </NuGetPackageImportStamp><br> </PropertyGroup><br> </Project>

文件已经经过过度简化,肯定是编译不过的了。不过,你可以意会。它会在某些 NuGet 包安装完后出现在 csproj 文件中。

什么情况下会出现 NuGetPackageImportStamp 节点

你也许会发现,并不是所有的 NuGet 包安装完后都会出现 NuGetPackageImportStamp 节点。实际上,只有那些会导致新 Import 文件部件的 NuGet 包才会出现这样的节点。

我们来了做个实验。

不会新增 NuGetPackageImportStamp

在项目中安装 Newtonsoft.Json。安装完后,你会看到仓库中有两个文件发生了变化:

▲ 两个文件发生了变化

一个是 packages.config 文件,这是传统的 NuGet 包管理方式所需要的一个文件,用于记录当前项目中管理的 NuGet 包信息。

1 2 3 4

<?xml version="1.0" encoding="utf-8"?><br> <packages><br>++ <package id="Newtonsoft.Json" version="11.0.2" targetFramework="net473" /><br> </packages>

另一个是 csproj 文件:

1 2 3 4 5 6 7 8 9

<?xml version="1.0" encoding="utf-8"?><br> <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"><br> <ItemGroup><br>++ <Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"><br>++ <HintPath>..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll</HintPath><br>++ </Reference><br> <Reference Include="System" /><br> <ItemGroup><br> </Project>

我们发现,安装 Newtonsoft.Json 是不会导致项目中新增 NuGetPackageImportStamp 节点的。

会新增 NuGetPackageImportStamp

现在,我们换另一个 NuGet 包来安装:StyleCop.MSBuild

同样是两个文件的变化,一个是 packages.config 文件。

1 2 3 4

<?xml version="1.0" encoding="utf-8"?><br> <packages><br>++ <package id="StyleCop.MSBuild" version="5.0.0" targetFramework="net471" developmentDependency="true" /><br> </packages>

另一个是 csproj 文件:

1 2 3 4 5 6 7 8 9 10 11 12 13 14

<?xml version="1.0" encoding="utf-8"?><br> <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"><br> <Import Project="..\..\packages\StyleCop.MSBuild.5.0.0\build\StyleCop.MSBuild.targets" Condition="Exists('..\..\packages\StyleCop.MSBuild.5.0.0\build\StyleCop.MSBuild.targets')" /><br> <PropertyGroup><br>++ <NuGetPackageImportStamp><br>++ </NuGetPackageImportStamp><br> </PropertyGroup><br>++ <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"><br>++ <PropertyGroup><br>++ <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText><br>++ </PropertyGroup><br>++ <Error Condition="!Exists('..\..\packages\StyleCop.MSBuild.5.0.0\build\StyleCop.MSBuild.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\StyleCop.MSBuild.5.0.0\build\StyleCop.MSBuild.targets'))" /><br>++ </Target><br> </Project>

我们发现,安装此 StyleCop.MSBuild NuGet 包的情况下,csproj 文件中新增了两个大的内容块:

  1. NuGetPackageImportStamp
  2. 用于 Import 一个 targets 文件的 Target

NuGetPackageImportStamp 的出现目的

我们发现 NuGetPackageImportStamp 其实是伴随着 Import 而出现的。而微软官方的注释也是诡异地说出了它的原因:

The overrides should ensure that Sets NuGetPackageImportStamp to a new random guid. This is a hack to let the project system know it is out of date. The value does not matter, it just needs to change.

这是为了让 Visual Studio 运行的时候,能够检测到 csproj 文件改变,以便重新加载这个项目,因为需要 Import 新的内容。在以前的 Visual Studio 版本中,会随机写下一段字符串;在新的版本中,它是个空字符串。

由于新的 csproj 文件能够识别到外部 Import 文件的改变,所以其实并不需要这样的机制来让 Visual Studio 感知到文件的改变。

在 Visual Studio 2017(工具版本 15.0)中,这个值会设为空,而在较低版本(14.0 及以下)这个值会设为一个随机的 guid。

以下是 NuGet 客户端设置此值的代码:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36

/// <summary> /// This method should be on the UI thread. The overrides should ensure that /// Sets NuGetPackageImportStamp to a new random guid. This is a hack to let the project system know it is out /// of date. /// The value does not matter, it just needs to change. /// </summary> protected static void UpdateImportStamp(IVsProjectAdapter vsProjectAdapter) { ThreadHelper.ThrowIfNotOnUIThread(); var propStore = vsProjectAdapter.VsHierarchy as IVsBuildPropertyStorage; if (propStore != null) { // <NuGetPackageImportStamp>af617720</NuGetPackageImportStamp> var stamp = Guid.NewGuid().ToString().Split('-')0; try { propStore.SetPropertyValue(NuGetImportStamp, string.Empty, (uint)_PersistStorageType.PST_PROJECT_FILE, stamp); } catch (Exception ex1) { ExceptionHelper.WriteErrorToActivityLog(ex1); } // Remove the NuGetImportStamp so that VC++ project file won't be updated with this stamp on disk, // which causes unnecessary source control pending changes. try { propStore.RemoveProperty(NuGetImportStamp, string.Empty, (uint)_PersistStorageType.PST_PROJECT_FILE); } catch (Exception ex2) { ExceptionHelper.WriteErrorToActivityLog(ex2); } } }

本文会经常更新,请阅读原文: https://blog.walterlv.com/post/the-empty-nuget-package-import-stamp.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接: https://blog.walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 ([email protected])

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-11-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
csproj项目文件中的已知属性
以下属性是基本的输出路径属性,可以在 Microsoft.NET.DefaultOutputPaths.targets 找到。
秦建辉
2025/07/10
50
理解 C# 项目 csproj 文件格式的本质和编译流程
发布于 2018-05-10 00:13 更新于 2018-08-12 08:11
walterlv
2018/09/18
2.9K0
理解 C# 项目 csproj 文件格式的本质和编译流程
MSBuild入门(续)
MSBuild基本概念(续) 在上一篇简单的介绍了下MSBuild中的四个基本块,每块介绍比较单薄,在这里对在大多数的项目模版生成的*.*proj文件中比较常见一些用法和概念做些补充。主要有一下几方面: MSBuild特殊字符:MSBuild保留的一些字符,以及XML中的特殊字符处理。 MSBuild条件: Condition特性,作用类似于C#的if。 MSBuild属性: 使用环境变量、保留属性、全局属性。 MSBuild项: 元数据、项转换。 MSBuild任务: ITask接口、UsingTask[
blackheart
2018/01/19
1.1K0
将 WPF、UWP 以及其他各种类型的旧 csproj 迁移成基于 Microsoft.NET.Sdk 的新 csproj
发布于 2018-01-15 16:04 更新于 2018-09-07 04:40
walterlv
2018/09/18
1.6K0
将 WPF、UWP 以及其他各种类型的旧 csproj 迁移成基于 Microsoft.NET.Sdk 的新 csproj
升级VS2019 16.11.5引起的error CS0246: The type or namespace name ‘FieldDescription’ could not be found (a
昨晚上看到VS2022的新的Preview版本发布,就连同VS2019一起升级到了最新版。
崔文远TroyCui
2021/10/18
1.4K0
升级VS2019 16.11.5引起的error CS0246: The type or namespace name ‘FieldDescription’ could not be found (a
VisualStudio 如何在 NuGet 包里面同时包含 DEBUG 和 RELEASE 的库
我在开发的时候需要使用到一些 DEBUG 库进行调试,但是我的库是通过 NuGet 给用户的,如果在 NuGet 里面使用到了 DEBUG 的库那么会让代码的运行效率降低。于是我就找到一个方法,可以在 NuGet 同时打包调试和发布的包,这样在用户调试的时候就可以使用调试的代码
林德熙
2019/04/22
2.1K0
VisualStudio 如何在 NuGet 包里面同时包含 DEBUG 和 RELEASE 的库
项目文件中的已知属性(知道了这些,就不会随便在 csproj 中写死常量啦)
发布于 2018-04-12 13:03 更新于 2018-08-29 01:36
walterlv
2018/09/18
1.7K0
Reading the Source Code of Microsoft.NET.Sdk, Writing the Creative Extension of Compiling
发布于 2018-06-30 12:27 更新于 2018-08-12 08:05
walterlv
2018/09/18
5050
Reading the Source Code of Microsoft.NET.Sdk, Writing the Creative Extension of Compiling
.NET魔法堂:工程构建基石->MSBuild
一、前言                               MSBuild是一个既熟悉又陌生的名字,Visual Studio的项目加载和构建均通过MSBuild来实现。VS中右键打开项目菜
^_^肥仔John
2018/01/18
2.1K0
.NET魔法堂:工程构建基石->MSBuild
手把手教你写dotnet core(入门篇)
dotnet core最低开发环境要求就是一个.NET SDK,在这里可以下载的到最新版本的SDK,各个平台都有.
李国宝
2020/01/02
2.2K0
手把手教你写dotnet core(入门篇)
[原创]自定义VS2010项目文件vcxproj动态管理inc lib
用户3519280
2023/07/06
2610
[原创]自定义VS2010项目文件vcxproj动态管理inc lib
(1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
发布于 2018-07-25 01:27 更新于 2018-07-26 23:23
walterlv
2018/09/18
1.5K0
(1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
.net core迁移实践:项目文件csproj的转换
随着net core的不断更新和生产可用,越来越多的人把现有的应用迁移和部署到net core平台。本文将分享迁移过程中的一个环节,给大家做一下参考。
梁规晓
2020/11/05
1.5K0
.net core迁移实践:项目文件csproj的转换
Roslyn 使用 Directory.Build.props 文件定义编译
本文告诉大家 Directory.Build.props 是什么有什么优点?如何使用 Directory.Build.props 文件定义编译
林德熙
2018/09/19
1.3K0
Roslyn 使用 Directory.Build.props 文件定义编译
MSBuild/Roslyn 和 NuGet 的 100 个坑
发布于 2018-07-04 13:29 更新于 2018-09-04 13:08
walterlv
2018/09/18
1.5K0
MSBuild/Roslyn 和 NuGet 的 100 个坑
项目文件中的已知 NuGet 属性(使用这些属性,创建 NuGet 包就可以不需要 nuspec 文件啦)
发布于 2018-05-10 13:49 更新于 2018-06-30 01:30
walterlv
2018/09/18
2.2K0
Visual Studio 2017 以前的旧格式的 csproj Import 进来的 targets 文件有时不能正确计算属性(PropertyGroup)和集合(ItemGroup)
我在之前的博客中有教大家如何编写 NuGet 工具包,其中就有编写 .targets 文件。
walterlv
2023/10/22
3250
在项目文件 / MSBuild / NuGet 包中编写扩展编译的时候,正确使用 props 文件和 targets 文件
.NET 扩展编译用的文件有 .props 文件和 .targets 文件。不给我选择还好,给了我选择之后我应该使用哪个文件来编写扩展编译的代码呢?
walterlv
2023/10/22
7220
解读 Microsoft.NET.Sdk 的源码,你能定制各种奇怪而富有创意的编译过程
发布于 2018-06-30 05:55 更新于 2018-08-12 08:05
walterlv
2018/09/18
1.5K0
解读 Microsoft.NET.Sdk 的源码,你能定制各种奇怪而富有创意的编译过程
.NET Core New csproj 如何发布可执行文件
  .NET工具链在最新的Preview3版本中,引入了新的MSBuild项目系统,项目文件又回归了.csproj的XML文件来管理,项目文件、包引用、程序集引用、.NET Core工具集、发布内容定义等内容。本文主要将主要讨论,如何在新的项目系统中(.csproj)发布可执行文件。我们都知道在之前的版本中,项目文件是通过project.json文件来管理项目和包引用的,那么通过删除 dependencies->Microsoft.NETCore.App-> "type": "platform" 子节点,并定义runtimes节点,来发布可执行文件(想了解的朋友可以阅读这篇文章) 。
yoyofx
2018/09/05
1.4K0
推荐阅读
csproj项目文件中的已知属性
50
理解 C# 项目 csproj 文件格式的本质和编译流程
2.9K0
MSBuild入门(续)
1.1K0
将 WPF、UWP 以及其他各种类型的旧 csproj 迁移成基于 Microsoft.NET.Sdk 的新 csproj
1.6K0
升级VS2019 16.11.5引起的error CS0246: The type or namespace name ‘FieldDescription’ could not be found (a
1.4K0
VisualStudio 如何在 NuGet 包里面同时包含 DEBUG 和 RELEASE 的库
2.1K0
项目文件中的已知属性(知道了这些,就不会随便在 csproj 中写死常量啦)
1.7K0
Reading the Source Code of Microsoft.NET.Sdk, Writing the Creative Extension of Compiling
5050
.NET魔法堂:工程构建基石->MSBuild
2.1K0
手把手教你写dotnet core(入门篇)
2.2K0
[原创]自定义VS2010项目文件vcxproj动态管理inc lib
2610
(1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
1.5K0
.net core迁移实践:项目文件csproj的转换
1.5K0
Roslyn 使用 Directory.Build.props 文件定义编译
1.3K0
MSBuild/Roslyn 和 NuGet 的 100 个坑
1.5K0
项目文件中的已知 NuGet 属性(使用这些属性,创建 NuGet 包就可以不需要 nuspec 文件啦)
2.2K0
Visual Studio 2017 以前的旧格式的 csproj Import 进来的 targets 文件有时不能正确计算属性(PropertyGroup)和集合(ItemGroup)
3250
在项目文件 / MSBuild / NuGet 包中编写扩展编译的时候,正确使用 props 文件和 targets 文件
7220
解读 Microsoft.NET.Sdk 的源码,你能定制各种奇怪而富有创意的编译过程
1.5K0
.NET Core New csproj 如何发布可执行文件
1.4K0
相关推荐
csproj项目文件中的已知属性
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档