一种把dll放在不同目录的巧妙方法

想必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 string path;

        /// <summary>
        /// 库文件列表
        /// </summary>
        protected static string[] Files
        {
            get
            {
                return new DirectoryInfo( path ).GetFiles().Select(p=>p.FullName).ToArray();
            }
        }

        /// <summary>
        /// 删除全部库文件
        /// </summary>
        public static void DeleteAllLibraryFiles()
        {
            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 );
        } 

    
        /// <summary>
        /// 删除全部库文件
        /// </summary>
        public static void DeleteAllLibraryFiles()
        {
            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)
                    {
                        
                    }
                }
            }
        }
}

建立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 );
            if( !fi1.Exists || !fi2.Exists || ( fi1.Length == fi2.Length && fi1.LastWriteTime == fi2.LastWriteTime ) )
            {
                return false;
            }

            return true;
        }


        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,氮素,

这种方式最简单稳定!

种方式最简单稳定!

方式最简单稳定!

式最简单稳定!

最简单稳定!

简单稳定!

单稳定!

稳定!

定!

完事,吃饭去

猜你喜欢

转载自www.cnblogs.com/HolyMeteor/p/9957247.html