You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET MAUI Android下获取CSharpCompilation的MetadataReference遇阻求替代方案

问题:Release模式下获取程序集字节流用于运行时编译

我需要在运行时编译类,必须引用System.Linq.dll、System.Collections.dll这类程序集,但Release模式构建时,Assembly.Location只返回程序集名称而非文件路径,导致无法用MetadataReference.CreateFromFile创建引用。有没有替代方案?


已尝试但无效的方案

  • 方案1:反射调用GetRawBytes
var methodInfo = assembly.GetType().GetMethod("GetRawBytes", BindingFlags.Instance | BindingFlags.NonPublic);
byte[] assemblyBytes = (byte[])methodInfo.Invoke(assembly, null);
var reference = MetadataReference.CreateFromImage(assemblyBytes);

问题:GetRawBytes在新版.NET中已被移除,无法调用。

  • 方案2:通过Hash类反射获取原始数据
var hash = new Hash(assembly);
var dllAsArray = (byte[])hash.GetType().GetMethod("GetRawData", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(hash, new object[0]);
var reference = MetadataReference.CreateFromImage(dllAsArray);

问题:Hash是Windows专属API,跨平台场景下无法使用。

  • 方案3:用BinaryFormatter序列化程序集
var formatter = new BinaryFormatter();
var ms = new MemoryStream();
formatter.Serialize(ms, assembly);
var reference = MetadataReference.CreateFromImage(ms.GetBuffer());

问题:BinaryFormatter已被官方弃用,编译阶段直接报错。

另外,尝试过FastReport仓库的Android适配方案,但调用TryGetRawMetadata()扩展方法时触发NotImplementedException。


可行的替代方案

方法1:使用Module.GetRawBytes(推荐,跨平台兼容新版.NET)

对于已加载的程序集,可通过其清单模块直接获取原始字节流,这是官方公开的API,无需反射,兼容性好:

byte[] assemblyBytes = assembly.ManifestModule.GetRawBytes();
var reference = MetadataReference.CreateFromImage(assemblyBytes);

方法2:从应用目录读取程序集文件

如果能确定程序集文件在应用运行目录下(比如未被单文件打包),可以直接读取文件字节:

string assemblyPath = Path.Combine(AppContext.BaseDirectory, "System.Linq.dll");
if (File.Exists(assemblyPath))
{
    byte[] assemblyBytes = File.ReadAllBytes(assemblyPath);
    var reference = MetadataReference.CreateFromImage(assemblyBytes);
}

注意:如果项目启用了单文件发布,需要在发布设置中保留必要的程序集文件,或者调整打包策略。

方法3:嵌入程序集为资源并读取

将需要引用的程序集添加到项目,设置“生成操作”为“嵌入的资源”,然后通过资源流读取:

// 资源名称格式:项目命名空间 + 程序集文件名
using var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("YourAppNamespace.System.Linq.dll");
if (stream != null)
{
    using var ms = new MemoryStream();
    stream.CopyTo(ms);
    var reference = MetadataReference.CreateFromImage(ms.ToArray());
}

内容的提问来源于stack exchange,提问作者Vitor P. Carneiro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 21:17:26