一种把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 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,氮素,

这种方式最简单稳定!

种方式最简单稳定!

方式最简单稳定!

式最简单稳定!

最简单稳定!

简单稳定!

单稳定!

稳定!

定!

完事,吃饭去

posted @ 2018-11-14 12:42  twtyypmb  阅读(1031)  评论(0编辑  收藏  举报