简体   繁体   English

如何将加载的程序集提供给C#中的Roslyn工作区

[英]How can I feed a loaded Assembly to a Roslyn Workspace in C#

I am enhancing an existing process with runtime code generation. 我正在使用运行时代码生成来增强现有流程。 The code I am creating at runtime needs access to some of the same dlls that the process creating the code is already referencing. 我在运行时创建的代码需要访问创建代码的进程已经引用的一些相同的dll。

Problem is that the process runs within some 3rd party software that loads dlls from resources and injects them into my process... thus I do not have access to either a dll on disk nor to the resource that contained the dll in the external wrapper. 问题是该进程在某些第三方软件中运行,该软件从资源加载dll并将它们注入我的进程...因此我无法访问磁盘上的dll或外部包装器中包含dll的资源。

As a result I am trying to use the assemblies I already have in memory and feed them into the Roslyn workspace into which I place my runtime code for compilation. 因此,我尝试使用我已经在内存中的程序集并将它们提供给Roslyn工作区,我将运行时代码放入其中进行编译。 I thought I could try serializing the Assembly with a binary formatter as per this SO: Opposite operation to Assembly Load(byte[] rawAssembly) 我想我可以尝试使用二进制格式化器来序列化程序集,如此SO: 对装配负载的相反操作(byte [] rawAssembly)

But even if I pretty much take the code as is: 但即使我几乎按原样采用代码:

Assembly yourAssembly = typeof(object).Assembly;
var formatter = new BinaryFormatter();
var ms = new MemoryStream();
formatter.Serialize(ms, yourAssembly);
var reloadedAssembly = Assembly.Load(ms.GetBuffer());

I get: 我明白了:

An exception of type 'System.BadImageFormatException' occurred in mscorlib.dll but was not handled in user code

None of the other search results seemed any better. 其他搜索结果似乎没有任何改善。

What I want to do is something like: 我想做的是:

var assemblyRef = MetadataReference.CreateFromAssembly(typeof(object).Assembly);
mySolution.AddMetadataReference(projectId, assemblyRef);

Any suggestions? 有什么建议么?

For a managed assembly loaded using Assembly.Load(byte[]) you can create a Roslyn MetadataReference like so: 对于使用Assembly.Load(byte [])加载的托管程序集,您可以创建一个Roslyn MetadataReference,如下所示:

var assembly = Assembly.Load(bytes);
var modulePtr = Marshal.GetHINSTANCE(assembly.ManifestModule);

var peReader = new PEReader((byte*)modulePtr, bytes.Length))
var metadataBlock = peReader.GetMetadata();
var moduleMetadata = ModuleMetadata.CreateFromMetadata((IntPtr)metadataBlock.Pointer, metadataBlock.Length);
var assemblyMetadata = AssemblyMetadata.Create(moduleMetadata);
var reference = assemblyMetadata.GetReference();

Note that this doesn't work for assemblies loaded from a file, since the layout in the memory is different. 请注意,这不适用于从文件加载的程序集,因为内存中的布局不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM