VS项目引用破坏了GUID的大小写敏感性

bub*_*ing 26 c# intellisense visual-studio visual-studio-2015 roslyn-code-analysis

自从升级到VS 2015以来,我的团队经历了随机古怪的事情,我肯定现在正在微软解决这个问题.一个非常讨厌的问题是我们似乎失去了项目引用,特别是在分支之后.我昨天开始研究我们解决方案的一个新分支,但发现这些类型无法识别,并且名称空间使用被引用为不必要的(因为它们是针对突然变得无法识别的类型).

项目中的引用没有显示任何指示引用问题的图标,但只是为了查看它是否可行,我删除并重新添加了项目引用,这导致其类型再次被识别.

当然,这更新了项目文件,因此我查看了已经进行了哪些更改.无法检测引用的项目与现在可以检测到的项目之间的唯一区别是GUID中的字母字符已从小写更改为大写.例如:

旧的,破碎的参考:

<ProjectReference Include="path/redacted">
    <Project>{95d34b2e-2ceb-499e-ab9e-b644b0af710d}</Project>
    <Name>Project.Name.Redacted</Name>
</ProjectReference>
Run Code Online (Sandbox Code Playgroud)

新的固定参考:

<ProjectReference Include="path/redacted">
    <Project>{95D34B2E-2CEB-499E-AB9E-B644B0AF710D}</Project>
    <Name>Project.Name.Redacted</Name>
</ProjectReference>
Run Code Online (Sandbox Code Playgroud)

我正在寻找发生这种情况的原因以及我如何解决它而无需手动删除和重新添加所有地方的引用(并且无需将所有项目文件GUID转换为大写).

我应该注意,这些"损坏的"引用并没有破坏构建,并且它们只在错误列表中显示为IntelliSense错误,而不是构建错误.所以,引用并没有真正被打破,它们刚刚破坏了IntelliSense(可以说更糟糕了?!).

yoy*_*oyo 18

TL; DR

Visual Studio在如何将GUID分配给项目如何在项目引用中指定这些GUID方面并不完全一致.我能够通过使用带有大括号的大写GUID和带ProjectGuid元素大括号的小写Project(在引用中)来解决问题.

背景

我们有一个大型解决方案(60多个C#项目),并且在解决方案Rebuild中经常出现问题,因为错误的构建顺序会导致无法解析尚未构建的引用项目(但应该已经构建).构建依赖关系和构建顺序似乎是正确的.MSBuild批量生成工作正常,从Visual Studio重建时只是一个问题.

使用大括号将所有项目GUID强制为大写,并使用大括号将所有项目引用GUID强制为小写,从而解决了问题.这通常是Visual Studio生成这些GUID的方式,但并非总是如此.

在一个全新的测试解决方案中进行一些调查,结果证明:

  1. 控制台应用程序项目的生成GUID是大写的大写.
  2. 类库项目的生成GUID最初是小写的,没有大括号.
  3. 如果为新项目引用添加了具有小写GUID的类库项目,则不仅添加了引用GUID,而且还将项目GUID转换为带大括号的大写.
  4. 如果创建了类库项目的副本,然后将其添加到解决方案中,则其GUID将替换为使用大写和大括号的新GUID.(但是,如果创建了副本并手动删除了其GUID,则Visual Studio不会将替换GUID插入.csproj文件中.)
  5. 项目引用GUID通常使用小写和大括号,但不知何故,我们的项目已经积累了大量的大写GUID引用.
  6. .sln中的GUID始终使用大写和大括号.

我能够通过用全部大写或全部小写替换引用GUID来修复我们破坏的重建 - 它是关于大小写混合的东西,它给出了Visual Studio的问题(可能是字典中的区分大小写的字符串键)某处?)由于Visual Studio通常会使用小写GUID添加引用,这是我选择使用的选项.

正则表达式搜索和替换

为了解决这个问题,我使用基于Notepad ++ regex的搜索并替换文件以强制.csproj文件中的所有ProjectGuids都是大括号(控制台应用程序的默认设置,并且在添加任何项目引用后将应用Visual Studio样式)项目):

Find what: (<ProjectGuid>)\{?([0-9a-f-]+)\}?(</ProjectGuid>)
Replace with: \1{\U\2}\E\3
Search in: *.csproj
Run Code Online (Sandbox Code Playgroud)

务必打开正则表达式搜索,然后关闭匹配大小写.并且不要搜索所有文件,或者你可以进行你不想要的更改,例如@.@.@ propyc文件中提到的*.xproj文件.(有关使用正则表达式更改案例的其他信息,请参阅此答案.)

然后,我将所有对项目的引用替换为使用带大括号的小写(这是Visual Studio通常所做的):

Find what: (<Project>)\{?([0-9a-f-]+)\}?(</Project>)
Replace with: \1{\L\2}\E\3
Search in: *.csproj
Run Code Online (Sandbox Code Playgroud)

完成这些更改后,Visual Studio解决方案重建现在可靠地运行.(至少在下一次流氓大写参考GUID潜入我们的项目之前.)

  • 我知道下次我们的GUID疯狂时,我将使用这个(不可避免的).干得好,把这一切都搞定了! (2认同)
  • @bubbleking我认为这也解决了我们所拥有的构建问题 - 很棒!有一点需要注意:您可能希望将查找/替换搜索约束为`*.csproj`文件.原因是,`*.xproj`文件 - .NET Core项目文件 - 似乎使用没有前导或花括号的GUIDS.因此,当我尝试您发布的解决方案时,它还添加了之前没有任何内容的大括号. (2认同)

jes*_*ing 6

项目系统中似乎有一个错误。这个 powershell 将遍历项目并使所有引用大写:

#FixGuids

get-childitem -recurse | ?{ @('.sln', '.csproj', '.vbproj') -contains $_.Extension } | %{
   [regex]::Replace((gc -raw $_.FullName), '[{(]?[0-9A-Fa-f]{8}[-]?([0-9A-Fa-f]{4}[-]?){3}[0-9A-Fa-f]{12}[)}]?', { return ([string]$args[0]).ToUpperInvariant() }) |
      Out-File $_.FullName -Encoding "UTF8
}
Run Code Online (Sandbox Code Playgroud)

这很简单。如果您依赖项目中的 guid 来获取引用以外的其他东西,您可能希望将其变成更智能的东西。

  • 制作 Visual Studio 2017。我不会期待 2015 年的更新 4。 (3认同)
  • 希望他们在 VS15 Update 4 中解决这个错误! (2认同)

Sla*_*wag 5

将VS2017 v15.7更新到v15.9时遇到了类似的问题。

对我来说,答案是关闭VS,清除.vs解决方案根目录中的隐藏文件夹,然后重新启动VS。