1. 程式人生 > >一種把dll放在不同目錄的巧妙方法

一種把dll放在不同目錄的巧妙方法

文件的 習慣 config 常用 log new foreach www. table

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

這種方式最簡單穩定!

種方式最簡單穩定!

方式最簡單穩定!

式最簡單穩定!

最簡單穩定!

簡單穩定!

單穩定!

穩定!

定!

完事,吃飯去

一種把dll放在不同目錄的巧妙方法