VS Project References Broken On Case Sensitivity of GUID

前端 未结 5 1064
旧巷少年郎
旧巷少年郎 2020-12-09 03:03

Since upgrading to VS 2015, my team has experienced random quirky things which I\'m sure are being worked out at Microsoft right now. One pretty annoying one is that we see

相关标签:
5条回答
  • 2020-12-09 03:30

    Today in visual studio 2019 (16.2.2) I was encountering build system issues where projects were being unnecessarily (and repeatedly) rebuilt whenever I initiated the building of my solution.

    (None of the usual steps resolved the build issues, eg deleting the ".vs" folder, or deleting "bin" and "obj" directories, etc).

    At first it appeared to be related to the character-casing of guids, because I was able to get the problem to go away by editing the guids and saving the project. However that was a red-herring ... I was unwittingly fixing the problem by changing the timestamps of all my csproj files. The build system seemed a lot happier after those timestamps were updated, and it stopped the annoying behavior (continuously attempting to rebuild projects that had already been built.)

    The character casing of the guids didn't end up being the problem at all. As far as I can tell, VS 2019 is ok with both upper- and lower-case guids. They can even mismatch the source project, based on my experimentation (eg. the original source project can use uppercase and referencing projects can use lowercase).

    If it is helpful to anyone, below is a powershell that will let you adjust the write-time of all csproj files under a path. This will be another trick I use whenever the msbuild system is misbehaving in 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
    }    
    }    
    }    
    
    0 讨论(0)
  • 2020-12-09 03:45

    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 -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
    }
    

    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.

    0 讨论(0)
  • 2020-12-09 03:50

    TL;DR

    Visual Studio isn't entirely consistent about how it assigns GUIDs to projects or how it specifies those GUIDs in project references. I was able to resolve the problem by using upper case GUIDs with braces for ProjectGuid elements and lower case with braces for Project elements (in references).

    Background

    We have a large solution (60+ C# projects), and were having regular issues with solution Rebuild as incorrect build order would cause failure to resolve referenced projects that had not yet been built (but should have been). Build Dependencies and Build Order appeared correct. MSBuild batch build worked fine, it was only a problem when rebuilding from Visual Studio.

    Forcing all project GUIDs to upper case with braces and all project reference GUIDs to lower case with braces fixed the problem. This is usually how Visual Studio generates these GUIDs, but not always.

    Doing some investigation in a brand new test solution, it turns out that:

    1. Generated GUIDs for console application projects are upper case with braces.
    2. Generated GUIDs for class library projects are initially lower case with no braces.
    3. If a new project reference is added a class library project with a lower case GUID, then not only is the reference GUID added, but the project GUID is converted to upper case with braces.
    4. If a copy of a class library project is made and then added to the solution then its GUID is replaced with a new one that uses upper case and braces. (But if a copy is made and its GUID manually removed, Visual Studio does not insert a replacement GUID into the .csproj file.)
    5. Project references GUIDs are usually use lower case and braces, but somehow our project had accumulated a bunch of upper case GUID references.
    6. GUIDs in the .sln always use upper case and braces.

    I was able to fix our broken rebuild by replacing the reference GUIDs with either all upper case or all lower case -- it's something about the mix of upper and lower case that was giving Visual Studio problems (perhaps case-sensitive string keys in a dictionary somewhere?) Since Visual Studio normally adds references with lower case GUIDs, that is the option I chose to go with.

    Regex Search & Replace

    To fix this, I used Notepad++ regex-based search and replace in files to force all ProjectGuids in .csproj files to be upper case with braces (the default for console applications, and the style Visual Studio will apply after adding any project reference to the project):

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

    Be sure to turn on regular expression search, and turn off match case. And don't search all files, or you may make changes you don't want, for example in *.xproj files, as noted by @AspNyc. (See this answer for additional info on use of regular expressions for changing case.)

    I then replaced all references to projects to use lower case with braces (which is what Visual Studio usually does):

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

    Having made these changes, Visual Studio solution rebuild now works reliably. (At least until next time rogue upper case reference GUIDs sneak into our project.)

    0 讨论(0)
  • 2020-12-09 03:52

    I suffered a similar issue when updating VS2017 v15.7 to v15.9.

    The answer for me was to close down VS, clear out the hidden .vs folder in my solution's root directory and restart VS.

    0 讨论(0)
  • 2020-12-09 03:55

    In order to use the answer in a git hook, I had to convert it to sed's regex syntax:

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

    Maybe someone finds this useful.

    0 讨论(0)
提交回复
热议问题