私はデバッガからのユーザー式の評価に取り組んでいます。私はメソッドコンテキストで式をコンパイルし、デバッガでILコードを注入したいと思っています。Roslyn:外部アセンブリから非公開フィールドで式をコンパイル
外部アセンブリからRoslynを使用したILコードへの非公開クラス/クラスフィールドを含む式をコンパイルできますか?
パブリッククラス 'Test'とプライベートメソッド 'PrivateMethod'で 'MyNamespace.dll'を取得しました。私はRoslynコンパイルから呼び出す必要があります。 は、私は次のコードでそれをやろうとしています:
public class TestCompilationOptions
{
public void Test()
{
var filePath = Path.Combine(Directory.GetCurrentDirectory(), "Output.dll");
Console.WriteLine("Preparing syntax tree");
string expressionString = @"
using System;
class XXX
{
public static void Main()
{
Console.WriteLine(MyNamespace.Test.PrivateMethod(2));
}
}";
//SyntaxTree targetTree = SyntaxFactory.ParseSyntaxTree(expressionString);
SyntaxTree targetTree = CSharpSyntaxTree.ParseText(expressionString);
Console.WriteLine("Preparing metadata references");
Assembly[] assemblys = new Assembly[4];
assemblys[0] = typeof(MyNamespace.Test).Assembly;
assemblys[1] = typeof(Console).Assembly;
assemblys[2] = typeof(object).Assembly;
assemblys[3] = Assembly.LoadFile(Path.Combine(Directory.GetCurrentDirectory(), "System.Runtime.dll"));
MetadataReference[] metadataReferences = MetadataFromAssembly(assemblys);
Console.WriteLine("Preparing default namespaces");
IEnumerable<string> DefaultNamespaces = new[] {"System", "System.Runtime"};
Console.WriteLine("Preparing compilation options");
CSharpCompilationOptions ReleaseDll = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, optimizationLevel: OptimizationLevel.Release);
CSharpCompilationOptions cOptions = ReleaseDll.WithUsings(DefaultNamespaces);
//.WithMetadataImportOptions(MetadataImportOptions.All);
Console.WriteLine("Getting compilation");
CSharpCompilation compilation = CSharpCompilation.Create("Output.dll", new SyntaxTree[] {targetTree}, metadataReferences, cOptions);
Console.WriteLine("Emitting compilation");
using (var dll = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
var emitRes = compilation.Emit(dll);
if (!emitRes.Success)
{
Console.WriteLine("Emited unsuccessfully!");
foreach (var d in emitRes.Diagnostics)
Console.WriteLine(d.ToString());
return;
}
}
}
public unsafe MetadataReference[] MetadataFromAssembly(Assembly[] assemblys)
{
MetadataReference[] result = new MetadataReference[assemblys.Length];
byte *b;
int length;
for (int i = 0; i < assemblys.Length; i++)
{
if (assemblys[i].TryGetRawMetadata(out b, out length))
{
var moduleMetadata = ModuleMetadata.CreateFromMetadata((IntPtr) b, length);
var assemblyMetadata = AssemblyMetadata.Create(moduleMetadata);
result[i] = assemblyMetadata.GetReference();
}
else
{
return null;
}
}
return result;
}
そして、次のエラーました:私は 'WithMetadataImportOptions' と 'MetadataImportOptions' Roslynの内部公衆とuncomenntedライン
作った(8,44): error CS0117: 'Test' does not contain a definition for 'privateMember'
を
//.WithMetadataImportOptions(MetadataImportOptions.All);
エラーが発生しました:
(8,44): error CS0122: 'Test.privateMember' is inaccessible due to its protection level
Roslyn APIを使用している可能性がありますか?
P.S. System.Reflectionを使用して非公開のフィールドシンボルを取得できますが、式をコンパイルするにはどうすればよいですか?