簡體   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