如何以编程方式使用Roslyn编译C#文件?

我读到你无法使用CSharpCodeProvider编译C#6.0,因此尝试使用Roslyn。 但我找不到一个很好的例子,如何加载文件,然后将其编译为DLL。

我应该如何使用Roslyn编写与此代码类似的内容? 或者还有其他方法吗? 现在,当我尝试编译包含对带有C#6.0代码的项目的引用的文件时,它只是说“命名空间’y’中不存在类型或命名空间名称’x’(您是否缺少程序集引用?)”

public string CompileCode() { var provider = new CSharpCodeProvider(); var outputPath = Path.Combine(Path.GetDirectoryName(_path), $"Code.dll"); var compilerparams = new CompilerParameters(_referencedAssemblies, outputPath); CompilerResults results = provider.CompileAssemblyFromFile(compilerparams, _path); var dllPath = results.PathToAssembly; if (!results.Errors.HasErrors) return dllPath; PrintError(results.Errors); return ""; } 

总之,我想:

  • 加载C#文件
  • 将它编译成一个DLL,以便我以后加载它。

我已经为您创建了一个样本供您使用。 您需要调整它以使用.Net 4.6的运行时间,以便CSharp6版本可供您使用。 我添加了一些细节,以便您可以选择编辑选项。

需要进行更改 – 将运行时路径更改为目标.Net 4.6在下面的示例中将LanguageVersion.Csharp5更改为LanguageVersion.Csharp5

  class Program { private static readonly IEnumerable DefaultNamespaces = new[] { "System", "System.IO", "System.Net", "System.Linq", "System.Text", "System.Text.RegularExpressions", "System.Collections.Generic" }; private static string runtimePath = @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\{0}.dll"; private static readonly IEnumerable DefaultReferences = new[] { MetadataReference.CreateFromFile(string.Format(runtimePath, "mscorlib")), MetadataReference.CreateFromFile(string.Format(runtimePath, "System")), MetadataReference.CreateFromFile(string.Format(runtimePath, "System.Core")) }; private static readonly CSharpCompilationOptions DefaultCompilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary) .WithOverflowChecks(true).WithOptimizationLevel(OptimizationLevel.Release) .WithUsings(DefaultNamespaces); public static SyntaxTree Parse(string text, string filename = "", CSharpParseOptions options = null) { var stringText = SourceText.From(text, Encoding.UTF8); return SyntaxFactory.ParseSyntaxTree(stringText, options, filename); } static void Main(string[] args) { var fileToCompile = @"C:\Users\DesktopHome\Documents\Visual Studio 2013\Projects\ConsoleForEverything\SignalR_Everything\Program.cs"; var source = File.ReadAllText(fileToCompile); var parsedSyntaxTree = Parse(source, "", CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp5)); var compilation = CSharpCompilation.Create("Test.dll", new SyntaxTree[] { parsedSyntaxTree }, DefaultReferences, DefaultCompilationOptions); try { var result = compilation.Emit(@"c:\temp\Test.dll"); Console.WriteLine(result.Success ? "Sucess!!" : "Failed"); } catch (Exception ex) { Console.WriteLine(ex); } Console.Read(); } 

这需要一些调整,但它应该给你想要的结果。 根据需要更改它。

您必须使用NuGet包Microsoft.CodeAnalysis.CSharp

 var syntaxTree = CSharpSyntaxTree.ParseText(source); CSharpCompilation compilation = CSharpCompilation.Create( "assemblyName", new[] { syntaxTree }, new[] { MetadataReference.CreateFromFile(typeof(object).Assembly.Location) }, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); using (var dllStream = new MemoryStream()) using (var pdbStream = new MemoryStream()) { var emitResult = compilation.Emit(dllStream, pdbStream); if (!emitResult.Success) { // emitResult.Diagnostics } }