8

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
}

エラーメッセージが回線assembly = Assembly.LoadFile(Path.Combine(Directory.GetCurrentDirectory(), @"Greeter.dll"));に表示され、次のように表示されます。

Im Modul wurde einAssemblymanifesterwartet。(Ausnahme von HRESULT:0x80131018)

これは大まかに次のように解釈されます

モジュールにはアセンブリマニフェストが必要でした。

誰かが私がここで欠けているものを知っていますか?

4

5 に答える 5

15

私はこれに出くわしました.受け入れられた答えがありますが、一般的には役に立たないと思います. だから、私のような将来の検索者のためにここに残しておきます.

コードの問題は 2 つあります。

EmitResult result = compilation.Emit(file);

EmitResult オブジェクトのプロパティを見ると、results.Diagnostics メンバーに 2 つのエラーがあることがわかります。

  1. メインメソッドが見つかりません
  2. クラス コンソールが見つかりませんでした

したがって、問題を解決するには、 1. 出力を dll としてマークする必要があります。 2. 「using System;」を追加する必要があります。APIに渡すコードに追加するか、「System.Console.WriteLine」と言います

次のコードは、これら 2 つの問題を修正するために変更を加えて動作します。

        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();
于 2012-07-13T16:54:36.510 に答える
2

私は Roslyn サポートをO2 Plarformに追加してきました。Roslyn サポートを使用して、1 行のコードをコンパイル (コード)、作成 (およびアセンブリ)、呼び出し (メソッド) する方法を 次に示します。

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 行でコンパイル、作成、実行: Roslyn を使用してメソッドを動的にコンパイルおよび実行する O2 スクリプト

更新: Roslyn 関連の多数の投稿とツール (O2 プラットフォームを使用して作成)については、http: //blog.diniscruz.com/search/label/Roslynを参照してください。

于 2012-06-11T11:27:30.377 に答える
1

次のようなリファレンス用の新しい 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 で...

于 2013-07-07T00:32:11.233 に答える
0

このコードは美しく機能しました:

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("<ENTER> 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
}
于 2012-05-25T09:28:35.287 に答える
-1

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);
}
于 2012-05-25T09:16:06.373 に答える