想必C#的开发者都遇到过这个问题,引用的dll都放在根目录下,随着项目的日益增大,根目录下充满了各种各样的dll,非常的不美观。

如果能够把dll按照想要的目录来存放,那么系统就美观多了,以下是我常用的程序各文件的分布:

  • 【3rdLibs】

    • NLog.dll
    • Newtonsoft.Json.dll
    • ……
  • 【MyLibs】
  • 【Resources】
  • 【Images】
  • Excecutable.exe
  • Excecuteble.exe.config

好吧我承认以上是抄袭的http://www.cnblogs.com/marvin/p/PutDllToSpecificFolder.html,因为本人不太习惯写客套话,

说回正事,在网上搜索了很多方法效果都不好,具体方法可以看一下前面那个链接,总结起来有几种

1.切换工作路径法,此方法在多线程时会让你出错到爽歪歪,

2.调用win32api的方法LoadLibrary,这种方法只有调用单dll的时候好使,一旦调用的dll本身有其他的依赖库的时候,就完蛋

3.参加博客文章一种调用dll的方式,把模块放入单独的文件夹,通过辅助exe去调用,这种方式的劣势详见链接

下面是本人认为最佳的方式,新建抽象类SeparationLibraryClass

/// <summary>
/// 用于分离库的类
/// </summary>
public abstract class SeparationLibraryClass
{
        /// <summary>
        /// 删除全部库文件
        /// </summary>
        protected static void DeleteAllFiles(string path)
        {
            if( string.IsNullOrWhiteSpace( path ) )
            {
                return;
            }
            DirectoryInfo di = new DirectoryInfo( path );
            if( di.Exists && di.GetFiles() != null )
            {
                foreach( var item in di.GetFiles() )
                {
                    try
                    {
                        File.Delete( item.Name );
                    }
                    catch( Exception e )
                    {                     }
                }
            }
        }
 }

使用SeparationLibraryClass方式如下

public class Test :SeparationLibraryClass
{
      
[DllImport( "Termb.dll", )]
public static extern int Foo( );
    static Test()
{
path = "ExternalLibrary/Test/";// 此地址下放入所有依赖的文件
Helper.SmartCopyFiles( path );
}
         private static readonly string path;
      
         public static void DeleteAllLibraryFiles()
        {
            DeleteAllFiles( path );
        }
}

建立Helper类

class Helper
{
/// <summary>
/// 对比文件并拷贝到相应位置
/// </summary>
/// <param name="file1">要想文件拷贝至此地址</param>
/// <param name="file2">原文件地址</param>
/// <returns>是否复制了文件</returns>
public static bool SmartCopyFile(string file1,string file2)
{
FileInfo fi1 = new FileInfo( file1 );
FileInfo fi2 = new FileInfo( file2 );
            // fi2存在且fi1不存在时或fi1和fi2不一致时复制
            if( fi2.Exists && !(fi1.Exists && fi1.Length == fi2.Length && fi1.LastWriteTime == fi2.LastWriteTime) )
            {
                fi2.CopyTo( fi1.FullName, true );
                return true;
            }             
            return false;
 } public static void SmartCopyFiles(string path) { DirectoryInfo di = new DirectoryInfo( path ); if( di.Exists && di.GetFiles() != null ) { foreach( var item in di.GetFiles() ) { SmartCopyFile( item.Name, item.FullName ); } } } }

最后在Test类所在的项目中创建文件夹路径ExternalLibrary/Test/,把所有依赖的文件都添加进去,然后每个依赖文件右键属性设置

你估计已经猜到实现方式了,没错,就是生成时把ExternalLibrary/Test/的所有内容复制到程序目录,然后运行时复制依赖文件在程序根目录,你也许绝对这种方式很low,氮素,

这种方式最简单稳定!

种方式最简单稳定!

方式最简单稳定!

式最简单稳定!

最简单稳定!

简单稳定!

单稳定!

稳定!

定!

完事,吃饭去

一种把dll放在不同目录的巧妙方法的更多相关文章

  1. DLL放在指定目录 以及设置dll调用路径

    一.DLL放在指定目录 在编写C# winform程序中,不免一个项目会有多个工程文件,而这些工程文件之间是相互引用的,所以不想将工程的生成结果(exe或者dll)放在当前工程bin目录下的Debug ...

  2. Unity获取插件所在目录的巧妙方法

    编写插件时,Unity没有提供当前被放置目录的功能.比如资源商店的一些插件需要放在Assets根目录下. 但通过脚本可以反求出所在目录,对于自己写的插件,就避免了类似问题: var scriptObj ...

  3. C#开发奇技淫巧三:把dll放在不同的目录让你的程序更整洁

    系列文章 C#开发奇技淫巧一:调试windows系统服务 C#开发奇技淫巧二:根据dll文件加载C++或者Delphi插件 C#开发奇技淫巧三:把dll放在不同的目录让你的程序更整洁 程序目录的整理 ...

  4. 关于jsp页面是放在webroot目录下和web-inf下优缺点

    CSDN问题: jsp放在webroot目录下 这样就可以让用户直接访问,jsp放在web-inf目录下就必须要通过请求才能访问.因此放在web-inf下jsp页面显得要安全. 既然这样 ,那是不是只 ...

  5. Windows提供了两种将DLL映像到进程地址空间的方法(隐式和显式)

    调用DLL,首先需要将DLL文件映像到用户进程的地址空间中,然后才能进行函数调用,这个函数和进程内部一般函数的调用方法相同.Windows提供了两种将DLL映像到进程地址空间的方法: 1. 隐式的加载 ...

  6. Windows提供了两种将DLL映像到进程地址空间的方法

    调用DLL,首先需要将DLL文件映像到用户进程的地址空间中,然后才能进行函数调用,这个函数和进程内部一般函数的调用方法相同.Windows提供了两种将DLL映像到进程地址空间的方法: 1. 隐式的加载 ...

  7. MSSTDFMT.dll系统文件(附2种MSSTDFMT.dll 注册方法)-系统增强

    MSSTDFMT.dll系统文件(附2种MSSTDFMT.dll 注册方法)-系统增强 msstdfmt.dll是微软标准数据格式对象相关动态链接库文件. msstdfmt.dll里面包含了定义好函数 ...

  8. dependency walker检查dll依赖关系目录设置的问题

    废话少说,直接上图 图中来看,似乎IESHIMS.DLL文件不存在报错,实际是因为没有加载IESHIMS.DLL所在的路径. 在我的电脑里面搜索有两个同名的dll,一个是32位的,一个是64位的. C ...

  9. U3D+SVN: 两份相同资源放在不同目录下导致META的更改

    U3D+SVN: 两份相同资源放在不同目录下导致META的更改. 实际情形:将地图文件map拷一份放在其它目录,回到UNITY编辑器,载入完成后加到磁盘,看到map文件夹下的所有meta都变红了. r ...

随机推荐

  1. bzoj 4291: [PA2015]Kieszonkowe

    Description 给定n个数,请从中选出若干个数,使得总和为偶数,请最大化这个总和.   Input 第一行包含一个正整数n(1<=n<=1000000). 第二行包含n个正整数a_ ...

  2. JAVA简易的注册会员系统

    public class Login { public static void main(String[] args) { System.out.println("*****欢迎进入注册系统 ...

  3. js处理浮点数计算误差

    众所周知,浮点计算会产生舍入误差的问题,比如,0.1+0.2,结果应该是0.3,但是计算的结果并不是如此,而是0.30000000000000004,这是使用基于IEEE754数值的浮点计算的通病,j ...

  4. fetch上传cookie数据方法

    Fetch 请求默认是不带cookie的.需要设置fetch的第二个参数: 先来看下,请求头部信息Request method - 使用的HTTP动词,GET, POST, PUT, DELETE, ...

  5. 【转】axios的基本使用

    axios的基本使用 vue更新到2.0之后,作者就宣告不再对vue-resource更新,而是推荐的 axios 基于 Promise 的 HTTP 请求客户端,可同时在浏览器和 node.js 中 ...

  6. [AGC002D] Stamp Rally (并查集+整体二分)

    Description 给你一个n个点m个条边构成的简单无向连通图,有Q组询问,每次询问从两个点x,y走出两条路径,使这两条路径覆盖z个点,求得一种方案使得路径上经过的变的最大编号最小. Input ...

  7. 【CodeChef】PARADE(费用流,最短路)

    题意: 思路: #include<cstdio> #include<iostream> #include<algorithm> #include<cstrin ...

  8. js2:事件的学习,弹出窗口,状态栏字改变,地图热点的使用

    原文发布时间为:2008-11-08 -- 来源于本人的百度文章 [由搬家工具导入] <html> <head> <title>js</title> & ...

  9. linux的进程管理

    进程就是正在运行的程序. 一个程序可以对应多个进程,但是一个进程只对应一个程序. 1.进程和进程控制的概念 查看进程状态: w+用户名  查看个别用户的进程 ps -aux   显示系统进程 a:代表 ...

  10. 点击事件与UICollectionView的代理事件的冲突问题

    发现的问题:在UIImageView上添加UICollectionView视图,点击UICollectionViewCell,不执行didSelectItemAtIndexPath的代理方法. 解决方 ...