当前位置: 首页 > backend >正文

c#编写的应用程序调用不在同一文件夹下的DLL

在C#应用程序中调用非同一文件夹下的DLL,可通过以下方法实现,确保代码整洁且运行稳定:


一、托管DLL(.NET程序集)

  1. 配置文件指定私有路径(推荐)
    修改App.configWeb.config,添加<probing>标签指定子目录:

    <configuration><runtime><assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><probing privatePath="Libs;ThirdParty" /> <!-- 多个目录用分号分隔 --></assemblyBinding></runtime>
    </configuration>
    
    • 作用:CLR会自动搜索指定子目录中的DLL(如LibsThirdParty)。
    • 限制:仅适用于托管DLL,且目录需在应用程序根目录下。
  2. 动态加载程序集(代码控制)
    订阅AssemblyResolve事件,手动加载DLL:

    AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => 
    {string dllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SubFolder", new AssemblyName(args.Name).Name + ".dll");return File.Exists(dllPath) ? Assembly.LoadFrom(dllPath) : null;
    };
    
    • 适用场景:需精确控制加载逻辑(如按条件选择x86/x64版本)。

二、非托管DLL(C/C++等原生库)

  1. 设置环境变量PATH
    在程序启动时添加DLL目录到PATH:

    string dllDir = Path.Combine(Environment.CurrentDirectory, "NativeLibs");
    Environment.SetEnvironmentVariable("PATH", Environment.GetEnvironmentVariable("PATH") + ";" + dllDir);
    
    • 原理:Windows搜索DLL时检查PATH环境变量。
  2. 修改当前工作目录
    临时切换目录后再调用DLL:

    string originalDir = Environment.CurrentDirectory;
    Environment.CurrentDirectory = Path.Combine(originalDir, "NativeLibs");
    // 调用DllImport方法 
    Environment.CurrentDirectory = originalDir; // 恢复目录 
    
    • 注意:可能影响其他文件操作,需谨慎使用。
  3. 完整路径DllImport(直接指定)
    在导入声明中写绝对路径:

    [DllImport(@"C:\MyApp\NativeLibs\mylib.dll")]
    public static extern void MyNativeMethod();
    
    • 缺点:路径硬编码,移植性差。

三、混合场景(托管+非托管依赖)

  • 嵌套依赖处理:若托管DLL依赖非托管DLL,需确保非托管DLL位于:
    • 应用程序根目录
    • PATH环境变量包含的目录
    • 或通过SetDllDirectoryAPI添加路径(需P/Invoke调用)。

四、调试与部署建议

  1. 调试配置(VS设置):
    • 项目属性 → 调试 → 工作目录 → 设为DLL所在目录。
    • 输出路径 → 指向DLL目录,实现编译时自动更新。
  2. 版本管理:
    • 通过配置文件绑定程序集版本,避免冲突(如<dependentAssembly>)[2][7]。
  3. 安全提示:
    • 验证外部DLL来源,防止恶意代码注入。
    • 确保DLL与应用程序架构匹配(x86/x64)。

总结方案选择

场景推荐方法
托管DLL在子目录配置文件<probing privatePath>
动态加载/条件选择DLLAssemblyResolve事件
非托管DLL设置PATH或修改工作目录
复杂依赖链结合环境变量+事件解析

通过合理组织目录结构(如/Libs/Native)并搭配上述技术,可显著提升项目可维护性。若遇版本冲突,参考强名称签名或绑定重定向。

http://www.xdnf.cn/news/19898.html

相关文章:

  • OpenLayers 入门篇教程 -- 章节三 :掌控地图的视野和交互
  • 下一代自动驾驶汽车系统XIL验证方法
  • 【Doris入门】Doris数据表模型使用指南:核心注意事项与实践
  • select, poll, epoll
  • PyTorch 损失函数与优化器全面指南:从理论到实践
  • 论文理解:Reflexion: Language Agents with Verbal Reinforcement Learning
  • 【正则表达式】 正则表达式运算法优先级的先后是怎么排序的?
  • 【Pytest】解决Pytest中Teardown钩子的TypeError:实例方法与类方法的调用差异
  • Java中最常用的设计模式
  • Mysql主从复制之延时同步
  • 【Linux基础】Linux系统管理:深入理解Linux运行级别及其应用
  • 面经分享二:Kafka、RabbitMQ 、RocketMQ 这三中消息中间件实现原理、区别与适用场景
  • 笔记:卷积神经网络(CNN)
  • VS2015+QT编译protobuf库
  • 【倒计时2个月】好•真题资源+专业•练习平台=高效备赛2025初中古诗文大会
  • 达人数据导出:小青苔如何让达人数据管理效率飙升?
  • 海康摄像头开发---JSON数据与图片分离
  • 近期刷题总结
  • ChartView的基本介绍与使用
  • 江协科技STM32学习笔记补充之004 基于XC6206P332MR(Torex)的5V到3.3V的电压转换电路分析
  • 2025年中国GEO优化服务机构官方信息汇总与能力概览
  • 《增广贤文》读书笔记(四)
  • 热烈庆祝 | 一二三物联网携这款产品入选2025年度山东省首台(套)技术装备生产企业及产品名单
  • “硬件初始化配置,包括芯片选型、时钟树设计、GPIO/外设参数设置”一般都是哪些需要配置
  • 腾讯云《意愿核身移动 H5》 快速完成身份验证接入
  • 【GitOps】初始Argo CD
  • Unity学习----【进阶】Addressables(一)--概述与简单的使用
  • 小企业环境-流水线管理
  • vue2头部布局示例
  • 基于https+域名的Frp内网穿透教程(Linux+Nginx反向代理)