繁体   English   中英

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

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

我正在使用运行时代码生成来增强现有流程。 我在运行时创建的代码需要访问创建代码的进程已经引用的一些相同的dll。

问题是该进程在某些第三方软件中运行,该软件从资源加载dll并将它们注入我的进程...因此我无法访问磁盘上的dll或外部包装器中包含dll的资源。

因此,我尝试使用我已经在内存中的程序集并将它们提供给Roslyn工作区,我将运行时代码放入其中进行编译。 我想我可以尝试使用二进制格式化器来序列化程序集,如此SO: 对装配负载的相反操作(byte [] rawAssembly)

但即使我几乎按原样采用代码:

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

我明白了:

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

其他搜索结果似乎没有任何改善。

我想做的是:

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

有什么建议么?

对于使用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();

请注意,这不适用于从文件加载的程序集,因为内存中的布局不同。

暂无
暂无

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

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