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

这种方式最简单稳定!

种方式最简单稳定!

方式最简单稳定!

式最简单稳定!

最简单稳定!

简单稳定!

单稳定!

稳定!

定!

完事,吃饭去

原文地址:https://www.cnblogs.com/HolyMeteor/p/9957247.html

时间: 2024-10-11 02:13:21

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

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

一.DLL放在指定目录 在编写C# winform程序中,不免一个项目会有多个工程文件,而这些工程文件之间是相互引用的,所以不想将工程的生成结果(exe或者dll)放在当前工程bin目录下的Debug目录或者Release目录,而是放在一个公共的目录下,比如DLLImport目录下,如何实现这个工程呢,我们知道,如果是C++,我们可以使用cmake来部署我的项目,同样在c#中也可以实现这样的功能,我们只需在每个工程的“属性”----“生成事件”----“生成后事件命令行”写入如下代码即可: IF

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

调用DLL,首先需要将DLL文件映像到用户进程的地址空间中,然后才能进行函数调用,这个函数和进程内部一般函数的调用方法相同.Windows提供了两种将DLL映像到进程地址空间的方法: 1. 隐式的加载时链接 这种方法需要DLL工程经编译产生的LIB文件,此文件中包含了DLL允许应用程序调用的所有函数的列表,当链接器发现应用程序调用了LIB文件列出的某个函数,就会在应用程序的可执行文件的文件映像中加入一些信息,这些信息指出了包含这个函数的DLL文件的名字.当这个应用程序运行时,也就是它的可执行文件

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

调用DLL,首先需要将DLL文件映像到用户进程的地址空间中,然后才能进行函数调用,这个函数和进程内部一般函数的调用方法相同.Windows提供了两种将DLL映像到进程地址空间的方法: 1. 隐式的加载时链接 这种方法需要DLL工程经编译产生的LIB文件,此文件中包含了DLL允许应用程序调用的所有函数的列表,当链接器发现应用程序调用了LIB文件列出的某个函数,就会在应用程序的可执行文件的文件映像中加入一些信息,这些信息指出了包含这个函数的DLL文件的名字.当这个应用程序运行时,也就是它的可执行文件

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

CSDN问题: jsp放在webroot目录下 这样就可以让用户直接访问,jsp放在web-inf目录下就必须要通过请求才能访问.因此放在web-inf下jsp页面显得要安全. 既然这样 ,那是不是只要是需要通过请求才可以访问的页面就一定要放在web-inf目录下呢还有放在webroot和放在web-inf目录下都各有什么明显的优缺点 .望大家讨论... 1楼: 通过设置过滤器,放在webroot下面的文件也可以实现不能直接访问.所以说放在哪里就看习惯是什么样了. 一般项目都是要求隐藏性的,只让

使用NSFileManager枚举目录种的内容(遍历目录)

需要获得目录的内容列表,使用enumeratorAtPath:方法或者directoryC ontentsAtPath:方法,可以完成枚举过程. 如果使用第一种enumeratorAtPath:方法,一次可以枚举指定目录中的每个文件.默认情况下,如果其中一个文件为目录,那么也会递归枚举它的内容.在这个过程中,通过向枚举对象发送一条skipDescendants消息,可以动态地阻止递归过程,从而不再枚举目录中的内容. 对于directoryContentsAtPath:方法,使用这个方法,可以枚举

为什么classes目录要放在WEB-INF目录下?

如题,今天项目运行报错 ...NoSuchBeanDefinitionException: No bean named 'shiroFilter' 异常交代的很清楚,web容器没有找到相应的bean.那么,查询后会从两个方面入手: 相应的xml配置文件有问题? 指定的bean没有发现? 然后逐一排查,和同事确认后排出第一个问题,因为同样的代码他的OK运行良好.重点就放到第二项问题了,顺着xml配置查找相应的类文件,都找到了.这下问题就头大了,配置好+文件都在,就是启动不了,难道是需要更换web容

配置类库dll所在的目录下的相对路径

当类库写好后,以Debug或Release生成后,将.txt文件拷贝到dll所在的目录下,这时配置(或读取).txt文件的路径可以设置为://获取和设置包括该应用程序的目录的名称string txtUrl = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + @"\XXX.txt";

jsp被转成servlet后eclipse把这个servlet放在哪个目录下呢?

马 克-to-win:(视频下载) (全部书籍)对于学有余力的同学,我最后再延伸讲一点.Eclipse运行jsp的时候,先把它变成一个servlet(发生在第一次访问jsp时).eclipse把这个servlet放在哪个目录下呢?我们可以按照下面的步骤找到它:右击项目/Run as/Run Configuration找到你的Tomcat Server/Argument其中找到deploy这个参数,它清清楚楚的标明,你的Servlet项目被部署到哪个目录下了!到那个目录附近,耐心打 开每个目录.仔

一种调用dll的巧妙方法

直接上代码,后面说应用场景 新建一个项目,引入需要调用的dll,如下 class Program { [DllImport( "soft.dll" )] static extern int CreditTrans( StringBuilder strin, StringBuilder strout ); static int Main( string[] args ) { if( args== null || args.Length < 1 ) { return -1; } St