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

low*_*key 7 c# assemblies 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("<ENTER> to continue");
            Console.ReadLine();

        }
    }
    // Thanks, http://blogs.msdn.com/b/csharpfaq/archive/2011/11/23/using-the-roslyn-symbol-api.aspx
}
Run Code Online (Sandbox Code Playgroud)

错误消息出现在行上assembly = Assembly.LoadFile(Path.Combine(Directory.GetCurrentDirectory(), @"Greeter.dll"));并读取

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

大致翻译为

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

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

小智 14

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

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

EmitResult result = compilation.Emit(file);
Run Code Online (Sandbox Code Playgroud)

如果查看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("<ENTER> to continue");
        Console.ReadLine();
Run Code Online (Sandbox Code Playgroud)


Din*_*ruz 2

我已经向O2 Plaform添加了 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
Run Code Online (Sandbox Code Playgroud)

这是一个执行类似于您的代码片段的版本(我添加了一个返回值):

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
Run Code Online (Sandbox Code Playgroud)

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

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