加载由Roslyn编译器生成的程序集

我正在使用Roslyn编译器生成Greeter.dll。 尝试加载DLL文件时出现问题。

这是代码:

using System; using Roslyn.Compilers; using Roslyn.Compilers.CSharp; using System.IO; using System.Reflection; using System.Linq; namespace LoadingAClass { class Program { static void Main(string[] args) { var syntaxTree = SyntaxTree.ParseCompilationUnit(@" class Greeter { static void Greet() { Console.WriteLine(""Hello, World""); } }"); var compilation = Compilation.Create("Greeter.dll", syntaxTrees: new[] { syntaxTree }, references: new[] { new AssemblyFileReference(typeof(object).Assembly.Location), new AssemblyFileReference(typeof(Enumerable).Assembly.Location), }); Assembly assembly; using (var file = new FileStream("Greeter.dll", FileMode.Create)) { EmitResult result = compilation.Emit(file); } assembly = Assembly.LoadFile(Path.Combine(Directory.GetCurrentDirectory(), @"Greeter.dll")); Type type = assembly.GetType("Greeter"); var obj = Activator.CreateInstance(type); type.InvokeMember("Greet", BindingFlags.Default | BindingFlags.InvokeMethod, null, obj, null); Console.WriteLine(" to continue"); Console.ReadLine(); } } // Thanks, http://blogs.msdn.com/b/csharpfaq/archive/2011/11/23/using-the-roslyn-symbol-api.aspx } 

assembly = Assembly.LoadFile(Path.Combine(Directory.GetCurrentDirectory(), @"Greeter.dll"));上发生错误消息assembly = Assembly.LoadFile(Path.Combine(Directory.GetCurrentDirectory(), @"Greeter.dll")); 和读

Im Modul wurde ein Assemblymanifest erwartet。 (Ausnahme von HRESULT:0x80131018)

大致翻译为

模块中预计会出现一个程序集清单。

有谁知道我在这里缺少什么?

我一直在为O2 Plarform添加Roslyn支持,以下是如何使用其Roslyn支持编译(代码),创建(和汇编)和调用(其方法)一行代码:

 return @"using System; class Greeter { static string Greet() { return ""Another hello!!""; }}" .tree().compiler("Great").create_Assembly().type("Greeter").invokeStatic("Greet"); //O2Ref:O2_FluentSharp_Roslyn.dll 

这是一个执行看起来像你的代码片段的版本(我添加了一个返回值):

 panel.clear().add_ConsoleOut(); var code = @" using System; class Greeter { static string Greet() { Console.WriteLine(""Hello, World""); return ""hello from here""; } }"; var tree = code.astTree(); if (tree.hasErrors()) return tree.errors(); var compiler = tree.compiler("Great") .add_Reference("mscorlib"); if (compiler.hasErrors()) return compiler.errors(); var assembly =tree.compiler("Great") .create_Assembly(); return assembly.type("Greeter") .invokeStatic("Greet"); //O2Ref:O2_FluentSharp_Roslyn.dll //O2File:_Extra_methods_Roslyn_API.cs //O2File:API_ConsoleOut.cs 

有关这些内容的更多详细信息和屏幕截图,请参阅此博客文章: 1行编译,创建和执行:O2脚本使用Roslyn动态编译和执行方法

更新:请参阅http://blog.diniscruz.com/search/label/Roslyn获取大量Roslyn相关post和工具(使用O2平台创建)

我偶然发现了这一点,即使你有一个接受的答案,我认为它一般都没有用。 所以,我将这里留给像我这样的未来搜索者。

代码的问题是两件事,你可以通过查看返回的值来找到它

 EmitResult result = compilation.Emit(file); 

如果查看EmitResult对象上的属性,您会发现results.Diagnostics成员中有2个错误。

  1. 找不到主要方法
  2. 找不到类控制台

因此,要解决此问题,1。您需要将输出标记为dll 2.您需要添加’using System;’ 您传递给API的代码或说’System.Console.WriteLine’

以下代码可以进行更改以修复这两个问题:

  var outputFile = "Greeter.dll"; var syntaxTree = SyntaxTree.ParseCompilationUnit(@" // ADDED THE FOLLOWING LINE using System; class Greeter { public void Greet() { Console.WriteLine(""Hello, World""); } }"); var compilation = Compilation.Create(outputFile, syntaxTrees: new[] { syntaxTree }, references: new[] { new AssemblyFileReference(typeof(object).Assembly.Location), new AssemblyFileReference(typeof(Enumerable).Assembly.Location), }, // ADDED THE FOLLOWING LINE options: new CompilationOptions(OutputKind.DynamicallyLinkedLibrary)); using (var file = new FileStream(outputFile, FileMode.Create)) { EmitResult result = compilation.Emit(file); } Assembly assembly = Assembly.LoadFrom("Greeter.dll"); Type type = assembly.GetType("Greeter"); var obj = Activator.CreateInstance(type); type.InvokeMember("Greet", BindingFlags.Default | BindingFlags.InvokeMethod, null, obj, null); Console.WriteLine(" to continue"); Console.ReadLine(); 

这段代码很漂亮:

 using System; using Roslyn.Compilers; using Roslyn.Compilers.CSharp; using System.IO; using System.Reflection; using System.Linq; namespace LoadingAClass { class Program { static void Main(string[] args) { var syntaxTree = SyntaxTree.ParseCompilationUnit(@" using System; namespace HelloWorld { class Greeter { public static void Greet() { Console.WriteLine(""Hello, World""); } } }"); string dllPath = Path.Combine(Directory.GetCurrentDirectory(), "Greeter.dll"); string pdbPath = Path.Combine(Directory.GetCurrentDirectory(), "Greeter.pdb"); var compilation = Compilation.Create(dllPath, new CompilationOptions( assemblyKind: AssemblyKind.DynamicallyLinkedLibrary )) .AddSyntaxTrees( syntaxTree ) .AddReferences(new AssemblyFileReference(typeof(object).Assembly.Location)) .AddReferences(new AssemblyFileReference(typeof(Enumerable).Assembly.Location)); EmitResult result; using (FileStream dllStream = new FileStream(dllPath, FileMode.OpenOrCreate)) using (FileStream pdbStream = new FileStream(pdbPath, FileMode.OpenOrCreate)) { result = compilation.Emit( executableStream: dllStream, pdbFileName: pdbPath, pdbStream: pdbStream); } if (result.Success) { //assembly = Assembly.LoadFile(Path.Combine(Directory.GetCurrentDirectory(), @"Greeter.dll")); Assembly assembly = Assembly.LoadFrom(@"Greeter.dll"); Type type = assembly.GetType("HelloWorld.Greeter"); var obj = Activator.CreateInstance(type); type.InvokeMember("Greet", BindingFlags.Default | BindingFlags.InvokeMethod, null, obj, null); } else { Console.WriteLine("No Go"); Console.WriteLine(result.Diagnostics.ToString()); } Console.WriteLine(" to continue"); Console.ReadLine(); } } // Thanks, http://blogs.msdn.com/b/csharpfaq/archive/2011/11/23/using-the-roslyn-symbol-api.aspx // Thanks, http://social.msdn.microsoft.com/Forums/en-US/roslyn/thread/d620a4a1-3a90-401b-b946-bfa1fc6ad7a2 } 

References有一个新的API,如下所示:

 var compilation = Compilation.Create(outputFile, syntaxTrees: new[] { syntaxTree }, references: new[] { new MetadataFileReference(typeof(object).Assembly.Location), new MetadataFileReference(typeof(Enumerable).Assembly.Location), }, options: new CompilationOptions(OutputKind.DynamicallyLinkedLibrary) ); 

这是9月份最新的Roslyn-CTP 2012 …

结果我需要创建一个pdb文件。

 using (FileStream dllStream = new FileStream(dllPath, FileMode.OpenOrCreate)) using (FileStream pdbStream = new FileStream(pdbPath, FileMode.OpenOrCreate)) { result = compilation.Emit( executableStream: dllStream, pdbFileName: pdbPath, pdbStream: pdbStream); }