C#非强签名dll搜索顺序

简介: C#非强签名dll搜索顺序

由于不是强签名dll,所以无效考虑全局程序集缓存 (GAC)。

预备工作

新建解决方案ClassLibrary1,新建类库ClassLibrary1,新建控制台程序ShowDllLoc。

利用VS添加引用。

一,利用app.config设置codebase,设置dll的加载路径为:codebaselibs\ClassLibrary1.dll 。

二,利用app.config设置私有目录为libs。

<?xml version="1.0" encoding="utf-8" ?>

<dependentAssembly>
      <assemblyIdentity name="ClassLibrary1"
                culture="neutral" />
      <codeBase version="1.0.0.0"
            href="codebaselibs\ClassLibrary1.dll" />
    </dependentAssembly>
  </assemblyBinding>
</runtime>

建立一个类库,只有一个函数

public class Class1
{
public static void ShowLoc()
{
Console.WriteLine(typeof(Class1).Assembly.Location);
}
}
建立控制台项目,主函数为:
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("begin ");
ClassLibrary1.Class1.ShowLoc();
Console.ReadKey();
}
}

实验

一,在codebaselibs、exe所在目录、ClassLibrary1、libs目录各存放一个ClassLibrary1.dll。

启动程序,结果如下:

begin

C:\Code\Test\ClassLibrary1\ShowDllLoc\bin\Debug\codebaselibs\ClassLibrary1.dll

结论:优先加载codebase设置目录的dll。

二,删除codebaselibs目录的dll。

启动程序,程序崩溃退出。

结论:如果设置了codebase只会在codebase目录寻找。

三,删除codebase设置。

启动程序,结果如下:

begin

C:\Code\Test\ClassLibrary1\ShowDllLoc\bin\Debug\ClassLibrary1.dll

优先加载 exe目录的dll。

四,删除exe所在目录的dll。

启动程序,结果如下:

begin

C:\Code\Test\ClassLibrary1\ShowDllLoc\bin\Debug\ClassLibrary1\ClassLibrary1.dll

优先加载dll同名目录的dll。

五,删除ClassLibrary1目录的dll。

begin

C:\Code\Test\ClassLibrary1\ShowDllLoc\bin\Debug\libs\ClassLibrary1.dll

结论:最后加载私有目录的dll。

动态加载

static void Main(string[] args)
{
Console.WriteLine("begin ");
Assembly asm = Assembly.Load(“ClassLibrary1”);
Console.WriteLine(asm.Location);
Console.ReadKey();
}

一,4个目录都有dll。启动程序,结果如下:

begin

C:\Code\Test\ClassLibrary1\ShowDllLoc\bin\Debug\ClassLibrary1.dll

结论:优先加载exe所在目录的dll。

二,删除exe目录的dll。启动程序,结果如下:

begin

C:\Code\Test\ClassLibrary1\ShowDllLoc\bin\Debug\ClassLibrary1\ClassLibrary1.dll

结论:优先加载和dll同名的目录。

三,删除和dll同名目录的dll。启动程序,结果如下:

begin

C:\Code\Test\ClassLibrary1\ShowDllLoc\bin\Debug\libs\ClassLibrary1.dll

四,删除私用目录的dll。启动程序,结果如下:

程序崩溃。

结论:动态加载dll,不会在codebase目录寻找。

自动加载会影响收到加载

如果同时手动加载和自动加载,手动加载和自动加载的都会加载codbase目录。

测试VS版本VS2022或VS2019。

static void Main(string[] args)
{
Console.WriteLine("begin ");
Assembly asm = Assembly.Load(“ClassLibrary1”);
ClassLibrary1.Class1.ShowLoc();
Console.WriteLine(asm.Location);
Console.ReadKey();
}
}

begin

C:\Code\Test\ClassLibrary1\ShowDllLoc\bin\Debug\codebaselibs\ClassLibrary1.dll

C:\Code\Test\ClassLibrary1\ShowDllLoc\bin\Debug\codebaselibs\ClassLibrary1.dll

更换调用顺序也是如此:

begin

C:\Code\Test\ClassLibrary1\ShowDllLoc\bin\Debug\codebaselibs\ClassLibrary1.dll

C:\Code\Test\ClassLibrary1\ShowDllLoc\bin\Debug\codebaselibs\ClassLibrary1.dll

如果添加了引用,但没有调用此类库的函数,此dll并不会自动加载。

手动加载不会影响自动加载

static void Main(string[] args)
{
Console.WriteLine("begin ");
string strPathName = AppDomain.CurrentDomain.BaseDirectory + “libs2\ClassLibrary1.dll”;
Assembly asm = Assembly.LoadFile(strPathName);
Console.WriteLine(asm.Location);
ClassLibrary1.Class1.ShowLoc();
Console.ReadKey();
}

手动加载成功,自动加载失败而崩溃。和是否设置codebase无关。

dllcalldll.dll引用另外一个dll

dllcalldll.dll和exe的app.config都配置了codebase,那个有效。经测试,无论exe是否配置codebase, dllcalldll.dll的codebase永远无效。

小技巧

可以手动通过修改ShowDllLoc.exe.config来临时修改codebase目录。

C# 动态加载dll


扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。

https://edu.csdn.net/course/detail/38771

如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程

https://edu.csdn.net/lecturer/6176

相关

下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版

https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17

或者 操作系统:win10 开发环境: VS2022 C++17

如无特殊说明,本算法用**C++**实现。

相关文章
|
7月前
|
C#
C# 解决引用dll,出现dll不可以使用等问题
C# 解决引用dll,出现dll不可以使用等问题
|
2月前
|
C#
Delphi可不可以制作出像c#那样的dll类库?
在Delphi中,创建DLL项目(如dll.dpr)并定义一个类TMyCls后,在另一个项目(如test.dpr)中可以引入此DLL并直接实例化和调用类的方法。然而,Delphi目前主要支持两种DLL形式:动态链接库(需显式声明exports,仅支持函数调用)和ActiveX DLL(需定义IDL接口)。这两种方式都较为繁琐。相比之下,C# 的DLL类库更为便捷,编写并编译后即可在其他项目中直接使用。
|
4月前
|
C#
C# WPF 将第三方DLL嵌入 exe
C# WPF 将第三方DLL嵌入 exe
96 0
|
4月前
|
C# 图形学 数据安全/隐私保护
Unity数据加密☀️ 二、使用Rider将C#代码生成DLL文件
Unity数据加密☀️ 二、使用Rider将C#代码生成DLL文件
|
6月前
|
安全 编译器 API
程序与技术分享:C#调用DLL的几种方法
程序与技术分享:C#调用DLL的几种方法
174 0
|
7月前
|
开发框架 前端开发 JavaScript
C# 结合JavaScript实现手写板签名并上传到服务器
C# 结合JavaScript实现手写板签名并上传到服务器
|
网络协议 C# C++
关于 C#调用一个C/C++dll库运行时实现多个应用(静态变量区分) 的解决方法
关于 C#调用一个C/C++dll库运行时实现多个应用(静态变量区分) 的解决方法
关于 C#调用一个C/C++dll库运行时实现多个应用(静态变量区分) 的解决方法
|
开发框架 .NET Java
C#下反射动态加载dll后如何卸载?
C#下反射动态加载dll后如何卸载?
C#编译时嵌入dll至生成的exe
C#编译时嵌入dll至生成的exe
333 0
|
Rust 测试技术 API
【Rust 实战】Rust与C#交互-生成DLL库
【Rust 实战】Rust与C#交互-生成DLL库
1235 0
【Rust 实战】Rust与C#交互-生成DLL库