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

如何在C#程序中嵌入含非托管代码的CLR程序集并运行时加载

嵌入含非托管代码的CLR程序集并运行时加载的实现方案

嘿,你的这个思路完全没问题!把包含非托管代码的CLR程序集作为嵌入资源打包到C#可执行文件里,然后运行时读取字节流加载,是完全可行的方案。我给你补充一些细节和优化点,帮你避免踩坑:

一、先确认嵌入资源的名称是否正确

这是最容易踩坑的环节:你传给GetManifestResourceStream的资源名称必须完全匹配实际的嵌入资源名。可以通过两种方式确认:

  • 右键项目 → 属性 → 资源 → 找到你嵌入的DLL,查看它的「资源名称」(通常是项目默认命名空间 + 文件名,如果DLL放在子文件夹里,还要加上文件夹路径,比如MyNamespace.SubFolder.MyCLRAssembly.dll)
  • 用代码遍历所有资源名来排查,直接打印出来看:
    foreach (var resourceName in Assembly.GetExecutingAssembly().GetManifestResourceNames())
    {
        Console.WriteLine(resourceName);
    }
    

二、优化你的加载代码(增加错误处理)

你的基础代码逻辑是对的,但加上错误处理会更健壮,能快速定位问题:

public static Assembly LoadEmbeddedCLRAssembly()
{
    var currentAssembly = Assembly.GetExecutingAssembly();
    const string targetResourceName = "MyNamespace.MyCLRAssembly.dll";

    using (var resourceStream = currentAssembly.GetManifestResourceStream(targetResourceName))
    {
        if (resourceStream == null)
        {
            throw new FileNotFoundException("嵌入的CLR程序集资源未找到,请检查资源名称是否正确", targetResourceName);
        }

        byte[] assemblyBytes = new byte[resourceStream.Length];
        int totalReadBytes = resourceStream.Read(assemblyBytes, 0, assemblyBytes.Length);
        
        // 确保资源被完整读取
        if (totalReadBytes != assemblyBytes.Length)
        {
            throw new IOException("读取嵌入资源时未获取到完整的程序集数据");
        }

        return Assembly.Load(assemblyBytes);
    }
}

三、非托管代码相关的注意事项

因为你的程序集包含非托管代码,别担心,Assembly.Load(byte[])仍然能正常加载它,CLR会自动处理非托管部分的加载逻辑,但要注意两点:

  • 如果非托管代码依赖其他外部DLL,这些依赖要么也一起嵌入到主程序中(同样用资源方式加载),要么确保运行时能在系统路径或程序目录下找到它们
  • 如果非托管代码有特定平台依赖(比如x86/x64),你的主C#程序也要设置对应的平台目标(右键项目 → 属性 → 生成 → 平台目标),否则会出现加载失败的情况

四、加载后的使用示例

加载完成后,你可以通过反射调用目标程序集中的类型和方法:

// 加载嵌入的程序集
var loadedAssembly = LoadEmbeddedCLRAssembly();
// 获取目标类型
var targetClassType = loadedAssembly.GetType("MyCLRAssembly.TargetClass");
// 创建实例
var classInstance = Activator.CreateInstance(targetClassType);
// 获取并调用目标方法
var targetMethod = targetClassType.GetMethod("TargetMethod");
targetMethod.Invoke(classInstance, new object[] { "参数1", 123 });

内容的提问来源于stack exchange,提问作者user5265160

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:29:13