28

自从升级到 VS 2015 以来,我的团队经历了随机的古怪事情,我确信这些事情现在正在 Microsoft 解决。一个非常烦人的问题是我们似乎丢失了项目引用,尤其是在分支之后。昨天我开始研究我们解决方案的一个新分支,结果发现类型无法识别,并且命名空间使用被引用为不必要的(因为它们用于突然变得无法识别的类型)。

项目中的引用没有显示任何表示引用有问题的图标,但只是为了看看它是否可以工作,我删除并重新添加了一个项目引用,这导致它的类型再次被识别。

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

旧的,损坏的参考:

<ProjectReference Include="path/redacted">
    <Project>{95d34b2e-2ceb-499e-ab9e-b644b0af710d}</Project>
    <Name>Project.Name.Redacted</Name>
</ProjectReference>

新的固定参考:

<ProjectReference Include="path/redacted">
    <Project>{95D34B2E-2CEB-499E-AB9E-B644B0AF710D}</Project>
    <Name>Project.Name.Redacted</Name>
</ProjectReference>

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

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

4

5 回答 5

20

TL;博士

Visual Studio 在如何将 GUID 分配给项目如何在项目引用中指定这些 GUID 方面并不完全一致。我能够通过使用带有大括号的大写 GUID 和带有大括号的小写 GUID 来解决这个问题ProjectGuidProject在参考资料中)。

背景

我们有一个大型解决方案(60 多个 C# 项目),并且解决方案 Rebuild 经常出现问题,因为不正确的构建顺序会导致无法解决尚未构建的引用项目(但应该已经构建)。Build Dependencies 和 Build Order 看起来是正确的。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++ 正则表达式的搜索和替换,以强制 .csproj 文件中的所有 ProjectGuid 为大写并带有大括号(控制台应用程序的默认设置,并且 Visual Studio 将在添加任何项目引用后应用样式项目):

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

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

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

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

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

于 2017-02-22T19:22:35.813 回答
9

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

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

于 2019-01-07T15:14:17.727 回答
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
}

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

于 2016-04-04T18:05:37.270 回答
2

为了在 git 挂钩中使用答案,我必须将其转换为 sed 的正则表达式语法:

sed -r "s/(<Project>\{?)([0-9A-F-]+)(\}?<\/Project>)/\1\L\2\E\3/g" sample.csproj

也许有人觉得这很有用。

于 2018-04-03T14:15:53.503 回答
1

今天在 Visual Studio 2019 (16.2.2) 中,我遇到了构建系统问题,每当我开始构建我的解决方案时,项目就会被不必要地(并且反复地)重建。

(通常的步骤都没有解决构建问题,例如删除“.vs”文件夹,或删除“bin”和“obj”目录等)。

起初它似乎与 guid 的字符大小写有关,因为我能够通过编辑 guid 并保存项目来解决问题。然而,这是一个红鲱鱼......我无意中通过更改我所有 csproj 文件的时间戳来解决问题。更新这些时间戳后,构建系统似乎更开心了,它停止了烦人的行为(不断尝试重建已经构建的项目。)

向导的字符大小写根本不是问题。据我所知,VS 2019 可以使用大写和小写的 guid。根据我的实验,它们甚至可能与源项目不匹配(例如,原始源项目可以使用大写字母,而引用项目可以使用小写字母)。

如果对任何人有帮助,下面是一个 powershell,它可以让您调整路径下所有 csproj 文件的写入时间。每当 msbuild 系统在 Visual Studio 中出现异常时,这将是我使用的另一个技巧。

$datenow = get-date

$files = Get-ChildItem -path "C:\Data\Workspaces\LumberTrack\" -recurse | where { $_.PSIsContainer -eq $false} 

foreach ($file in $files)
{
if ($file.Extension -eq ".csproj") 
{
   Set-ItemProperty $file.FullName LastWriteTime $datenow
   Write-Output $file.FullName
}    
}    
}    
于 2019-08-26T16:43:24.030 回答