How can I resolve all links with Roslyn OpenSolutionAsync?

I am trying to open RoslynLight.sln using OpenSolutionAsync and then iterate over all projects. For my purposes, I need a semantic model and allowed links. Thanks to the combination of this issue and this question , I came up with this partial solution:

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(); } } } 

The magazine for this program is too large to publish, but the work around only works for certain projects. For example, rosyln \ src \ compilers \ Core \ Desktop \ CodeAnalysis.Desktop.csproj has no errors, but roslyn \ src \ Compilers \ CSharp \ Portable \ CSharpCodeAnalysis.csproj has:

 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' 

... and many others. It seems to me that I could make this work for an arbitrary project / solution very hacks. Did I miss something?

+5
source share
2 answers

You only need to add links to the facade if the project is aimed at a "complete" .NET infrastructure. Therefore, if you first look at existing links, if there are links that link to Reference Assemblies \ Microsoft.NETPortable \ v4.5 \ Profile \ ... then you do not need to add them.

+3
source

I consider this fix in the MSBuild targets, but at the same time, the following workaround should be used to solve this problem. Instead of using:

 MSBuildWorkspace.Create(); 

using:

 MSBuildWorkspace.Create(new Dictionary<string, string> { { "CheckForSystemRuntimeDependency", "true" } }); 
+4
source

Source: https://habr.com/ru/post/984864/


All Articles