一种把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,氮素,
这种方式最简单稳定!
种方式最简单稳定!
方式最简单稳定!
式最简单稳定!
最简单稳定!
简单稳定!
单稳定!
稳定!
定!
!
完事,吃饭去