2015-04-02 4 views
5

Ich versuche RoslynLight.sln mit OpenSolutionAsync zu öffnen und dann durch alle Projekte zu iterieren. Für meine Zwecke brauche ich ein semantisches Modell und löste Referenzen auf. Durch eine Kombination dieser issue und this question, habe ich in diesem Teil-Lösung kam:Wie kann ich alle Referenzen mit Roslyns OpenSolutionAsync auflösen?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using Microsoft.CodeAnalysis; 
using Microsoft.CodeAnalysis.MSBuild; 
using System.IO; 

namespace OpenRoslyn 
{ 
    class Program 
    { 
    static void Main(string[] args) 
    { 

     var msbw = MSBuildWorkspace.Create(); 
     var sln = msbw.OpenSolutionAsync(@"C:\Users\carr27\Documents\GitHub\roslyn\src\RoslynLight.sln").Result; 
     //var proj = sln.Projects.First(x => x.Name == "CodeAnalysis.Desktop"); 
     var messages = new List<string>(); 
     foreach (var p in sln.Projects) 
     { 
     Console.WriteLine(p.FilePath); 
     messages.Add(p.FilePath); 
     var facadesDir = @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6\Facades\"; 
     var proj = p.AddMetadataReference(MetadataReference.CreateFromAssembly(typeof(object).Assembly)); 
     proj = proj.AddMetadataReference(MetadataReference.CreateFromFile(facadesDir + "System.Runtime.dll")); 
     proj = proj.AddMetadataReference(MetadataReference.CreateFromFile(facadesDir + "System.Runtime.Extensions.dll")); 
     proj = proj.AddMetadataReference(MetadataReference.CreateFromFile(facadesDir + "System.IO.dll")); 
     proj = proj.AddMetadataReference(MetadataReference.CreateFromFile(facadesDir + "System.Threading.Tasks.dll")); 
     proj = proj.AddMetadataReference(MetadataReference.CreateFromFile(facadesDir + "System.Text.Encoding.dll")); 
     proj = proj.AddMetadataReference(MetadataReference.CreateFromFile(facadesDir + "System.Reflection.dll")); 
     try 
     { 
      var cu = proj.GetCompilationAsync().Result; 
      // here I would do useful work, but for know I just get diagnostics 
      foreach (var e in cu.GetDiagnostics().Where(x => x.Severity == DiagnosticSeverity.Error)) 
      { 
      Console.WriteLine("{0}: {1}", e.Location, e.GetMessage()); 
      messages.Add(String.Format("{0}: {1}", e.Location, e.GetMessage())); 
      } 
     } 
     catch (AggregateException e) 
     { 
      foreach(var ie in e.InnerExceptions) 
      { 
      Console.WriteLine(ie.Message); 
      messages.Add(ie.Message); 
      } 

     } 
     catch (Exception e) 
     { 
      Console.WriteLine(e.Message); 
      messages.Add(e.Message); 
     } 
     } 
     File.WriteAllLines("log.txt", messages); 
     Console.WriteLine("done."); 
     Console.ReadKey(); 
    } 
    } 
} 

Das Protokoll für dieses Programm ist zu groß für mich, zu schreiben, aber die Arbeit rund um funktioniert nur für bestimmte Projekte. Zum Beispiel rosyln \ src \ Compiler \ Core \ Desktop \ CodeAnalysis.Desktop.csproj keine Fehler hat, aber roslyn \ src \ Compilers \ CSharp \ Tragbarer \ CSharpCodeAnalysis.csproj hat:

None: Multiple assemblies with equivalent identity have been imported: 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\Profile\Profile7\System.Threading.Tasks.dll' and 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6\Facades\System.Threading.Tasks.dll'. Remove one of the duplicate references. 
None: Multiple assemblies with equivalent identity have been imported: 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\Profile\Profile7\System.Text.Encoding.dll' and 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6\Facades\System.Text.Encoding.dll'. Remove one of the duplicate references. 
None: Multiple assemblies with equivalent identity have been imported: 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\Profile\Profile7\System.Runtime.Extensions.dll' and 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6\Facades\System.Runtime.Extensions.dll'. Remove one of the duplicate references. 
None: Multiple assemblies with equivalent identity have been imported: 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\Profile\Profile7\System.Runtime.dll' and 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6\Facades\System.Runtime.dll'. Remove one of the duplicate references. 
None: Multiple assemblies with equivalent identity have been imported: 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\Profile\Profile7\System.Reflection.dll' and 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6\Facades\System.Reflection.dll'. Remove one of the duplicate references. 
None: Multiple assemblies with equivalent identity have been imported: 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.5\Profile\Profile7\System.IO.dll' and 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6\Facades\System.IO.dll'. Remove one of the duplicate references. 
SourceFile(C:\Users\carr27\Documents\GitHub\roslyn\src\Compilers\CSharp\Portable\BoundTree\UnboundLambda.cs[9068..9109)): The type 'ConcurrentDictionary<TKey, TValue>' exists in both 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' and 'System.Collections.Concurrent, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' 
SourceFile(C:\Users\carr27\Documents\GitHub\roslyn\src\Compilers\CSharp\Portable\BoundTree\UnboundLambda.cs[9203..9250)): The type 'ConcurrentDictionary<TKey, TValue>' exists in both 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' and 'System.Collections.Concurrent, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' 

... und viele Andere. Es scheint mir, dass ich diese Arbeit für ein willkürliches Projekt/eine Lösung sehr hacky machen könnte. Fehle ich etwas?

Antwort

3

Sie müssen die Fassadenreferenzen nur hinzufügen, wenn das Projekt auf das "vollständige" .NET-Framework abzielt. Wenn Sie sich also zuerst die vorhandenen Referenzen ansehen, sollten Referenzen, die von Reference Assemblies \ Microsoft.NETPortable \ v4.5 \ Profile \ ... stammen, nicht hinzugefügt werden.

+0

Thank you! Die Suche nach fehlenden Referenzen hat fast funktioniert, aber es gibt immer noch (zumindest) ein Projekt mit fehlenden Referenzen (glaube ich). Wenn ich BasicCodeAnalysis.Desktop.vbproj öffne, bekomme ich eine ganze Reihe von Typfehlern: [gist] (https://gist.github.com/scottcarr/cedcf98060159cdac418#file-gistfile1-txt) Irgendwelche Ideen? –

+0

Es scheint, ich bekomme viel mehr Fehler für VB als C#. Wenn ich versuche, nur alle C# -Projekte in RoslynLight.sln zu öffnen, erhalte ich eine anschauliche Anzahl von Fehlern: https://gist.github.com/scottcarr/fdc07fad670be7006852#file-gistfile1-txt. Der Code ist hier: https: //github.com/scottcarr/roslyn_repros –

+0

Ihre VB-Fehler würden aussehen, als gäbe es etwas, das mit VB-to-C# -Projekt Referenzen glitt. Es sieht so aus, als ob die VB-Seite in unserem "gemeinsamen" Code, der in C# geschrieben ist, nichts finden kann. –

4

Ich versuche, dies in den MSBuild-Zielen zu beheben, aber in der Zwischenzeit sollte die folgende Problemumgehung das Problem beheben. Anstelle der Verwendung von:

MSBuildWorkspace.Create(); 

Verwendung:

MSBuildWorkspace.Create(new Dictionary<string, string> { { "CheckForSystemRuntimeDependency", "true" } }); 
Verwandte Themen