VS项目参考文献破坏了GUID的案例敏感性

时间:2016-03-24 15:53:36

标签: c# visual-studio visual-studio-2015 intellisense roslyn-code-analysis

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

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

当然,这更新了项目文件,因此我查看了已经进行了哪些更改。无法检测引用的项目与现在可以检测到的项目之间的唯一区别是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转换为大写)。 / p>

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

5 个答案:

答案 0 :(得分:15)

<强> TL; DR

Visual Studio在如何将GUID分配给项目如何在项目引用中指定这些GUID方面并不完全一致。我能够通过使用带有ProjectGuid元素大括号的大写GUID和带有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始终使用大写和大括号。
  7. 我能够通过用全部大写或全部小写替换引用GUID来修复我们破坏的重建 - 它是关于大写和小写混合的东西,它给出了Visual Studio问题(可能是区分大小写的字符串键在某个字典中?)由于Visual Studio通常会添加带小写GUID的引用,这是我选择使用的选项。

    正则表达式搜索&amp;取代

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

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

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

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

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

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

答案 1 :(得分:3)

There's a bug in the projectsystem it seems. This powershell will loop over projects and make all references upper case:

#FixGuids

get-childitem -recurse | ?{ @('.sln', '.csproj', '.vbproj') -contains $_.Extension } | %{
   [regex]::Replace((gc $_.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
}

It's quite simplistic. If you rely on guids in your projects for something other than references, you may want to turn it into something more intelligent.

答案 2 :(得分:2)

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

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

答案 3 :(得分:1)

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

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

也许有人觉得这很有用。

答案 4 :(得分:1)

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

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

起初它似乎与Guid的字符框有关,因为我能够通过编辑Guid并保存项目来解决问题。但这真是一条红线……我无意中通过更改所有csproj文件的时间戳来解决此问题。在更新了这些时间戳之后,构建系统看起来更加快乐,并且它停止了令人讨厌的行为(不断尝试重建已经构建的项目。)

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

如果对任何人有帮助,请使用以下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
}    
}    
}