首页 文章

如何获取代码所在程序集的路径?

提问于
浏览
686

有没有办法获取当前代码所在的程序集的路径?我不想要调用程序集的路径,只需要包含代码的路径 .

基本上我的单元测试需要读取一些相对于dll的xml测试文件 . 无论测试dll是从TestDriven.NET,MbUnit GUI还是其他东西运行,我都希望路径始终正确解析 .

Edit :人们似乎误解了我的要求 .

我的测试库位于说

C:\ projects \ myapplication \ daotests \ bin \ Debug \ daotests.dll

我想得到这条道路:

C:\ projects \ myapplication \ daotests \ bin \ Debug \

当我从MbUnit Gui运行时,到目前为止,这三个建议都让我失望:

  • Environment.CurrentDirectory 给出c:\ Program Files \ MbUnit

  • System.Reflection.Assembly.GetAssembly(typeof(DaoTests)).Location 给出C:\ Documents and Settings \ george \ Local Settings \ Temp \ .... \ DaoTests.dll

  • System.Reflection.Assembly.GetExecutingAssembly().Location 与前一个相同 .

27 回答

  • 64

    我使用它来获取Bin目录的路径:

    var i = Environment.CurrentDirectory.LastIndexOf(@"\");
    var path = Environment.CurrentDirectory.Substring(0,i);
    

    你得到这个结果:

    “c:\ users \ ricooley \ documents \ visual studio 2010 \ Projects \ Windows_Test_Project \ Windows_Test_Project \ bin”

  • 9

    在Windows窗体应用程序中,您只需使用 Application.StartupPath

    但对于DLL和控制台应用程序,代码更难记住......

    string slash = Path.DirectorySeparatorChar.ToString();
    string root = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
    
    root += slash;
    string settingsIni = root + "settings.ini"
    
  • 0
    var assembly = System.Reflection.Assembly.GetExecutingAssembly();
    var assemblyPath = assembly.GetFiles()[0].Name;
    var assemblyDir = System.IO.Path.GetDirectoryName(assemblyPath);
    
  • 11

    您可以通过获取bin路径AppDomain.CurrentDomain.RelativeSearchPath

  • 6

    这很简单:

    var dir = AppDomain.CurrentDomain.BaseDirectory;
    
  • 927

    与John的答案相同,但是一种稍微冗长的扩展方法 .

    public static string GetDirectoryPath(this Assembly assembly)
    {
        string filePath = new Uri(assembly.CodeBase).LocalPath;
        return Path.GetDirectoryName(filePath);            
    }
    

    现在你可以这样做:

    var localDir = Assembly.GetExecutingAssembly().GetDirectoryPath();
    

    或者如果您愿意:

    var localDir = typeof(DaoTests).Assembly.GetDirectoryPath();
    
  • 44

    这就是我提出的 . In between web projects, unit tests (nunit and resharper test runner) ;我发现这对我有用 .

    我一直在寻找代码来检测构建的配置, Debug/Release/CustomName . 唉, #if DEBUG . 所以如果有人可以改善那个!

    随意编辑和改进 .

    Getting app folder . 对于web根,unittests有用,可以获取测试文件的文件夹 .

    public static string AppPath
    {
        get
        {
            DirectoryInfo appPath = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);
    
            while (appPath.FullName.Contains(@"\bin\", StringComparison.CurrentCultureIgnoreCase)
                    || appPath.FullName.EndsWith(@"\bin", StringComparison.CurrentCultureIgnoreCase))
            {
                appPath = appPath.Parent;
            }
            return appPath.FullName;
        }
    }
    

    Getting bin folder :用于使用反射执行程序集 . 如果由于构建属性而在那里复制文件 .

    public static string BinPath
    {
        get
        {
            string binPath = AppDomain.CurrentDomain.BaseDirectory;
    
            if (!binPath.Contains(@"\bin\", StringComparison.CurrentCultureIgnoreCase)
                && !binPath.EndsWith(@"\bin", StringComparison.CurrentCultureIgnoreCase))
            {
                binPath = Path.Combine(binPath, "bin");
                //-- Please improve this if there is a better way
                //-- Also note that apps like webapps do not have a debug or release folder. So we would just return bin.
    #if DEBUG
                if (Directory.Exists(Path.Combine(binPath, "Debug"))) 
                            binPath = Path.Combine(binPath, "Debug");
    #else
                if (Directory.Exists(Path.Combine(binPath, "Release"))) 
                            binPath = Path.Combine(binPath, "Release");
    #endif
            }
                return binPath;
        }
    }
    
  • 7
    AppDomain.CurrentDomain.BaseDirectory
    

    适用于MbUnit GUI .

  • 6

    当开发人员可以更改代码以包含所需的代码段时,所有建议的答案都有效,但如果您想在不更改任何代码的情况下执行此操作,则可以使用Process Explorer .

    它将列出系统上所有正在执行的dll,您可能需要确定正在运行的应用程序的进程ID,但这通常不会太困难 .

    我已经写了一个完整的描述,如何为II内部的dll做这个 - http://nodogmablog.bryanhogan.net/2016/09/locating-and-checking-an-executing-dll-on-a-running-web-server/

  • 0

    据我所知,大多数其他答案都有一些问题 .

    disk-based (as opposed to web-based), non-GACed assembly执行此操作的正确方法是使用当前正在执行的程序集的 CodeBase 属性 .

    这将返回一个URL( file:// ) . 而不是乱用string manipulationUnescapeDataString,这可以通过利用 UriLocalPath 属性进行最小的转换 .

    var codeBaseUrl = Assembly.GetExecutingAssembly().CodeBase;
    var filePathToCodeBase = new Uri(codeBaseUrl).LocalPath;
    var directoryPath = Path.GetDirectoryName(filePathToCodeBase);
    
  • 2

    我已经定义了以下属性,因为我们经常在单元测试中使用它 .

    public static string AssemblyDirectory
    {
        get
        {
            string codeBase = Assembly.GetExecutingAssembly().CodeBase;
            UriBuilder uri = new UriBuilder(codeBase);
            string path = Uri.UnescapeDataString(uri.Path);
            return Path.GetDirectoryName(path);
        }
    }
    

    Assembly.Location 属性有时会在使用NUnit(其中程序集从临时文件夹运行)时给出一些有趣的结果,所以我更喜欢使用 CodeBase ,它以URI格式提供路径,然后 UriBuild.UnescapeDataString 在开头删除 File://GetDirectoryName 更改它到正常的Windows格式 .

  • 282

    这应该工作:

    ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
    Assembly asm = Assembly.GetCallingAssembly();
    String path = Path.GetDirectoryName(new Uri(asm.EscapedCodeBase).LocalPath);
    
    string strLog4NetConfigPath = System.IO.Path.Combine(path, "log4net.config");
    

    我使用它来部署DLL文件库以及一些配置文件(这是使用DLL文件中的log4net) .

  • 1

    我一直在使用Assembly.CodeBase而不是Location:

    Assembly a;
    a = Assembly.GetAssembly(typeof(DaoTests));
    string s = a.CodeBase.ToUpper(); // file:///c:/path/name.dll
    Assert.AreEqual(true, s.StartsWith("FILE://"), "CodeBase is " + s);
    s = s.Substring(7, s.LastIndexOf('/') - 7); // 7 = "file://"
    while (s.StartsWith("/")) {
        s = s.Substring(1, s.Length - 1);
    }
    s = s.Replace("/", "\\");
    

    它's been working, but I' m不再确定它是100%正确的 . http://blogs.msdn.com/suzcook/archive/2003/06/26/assembly-codebase-vs-assembly-location.aspx的页面说:

    "The CodeBase is a URL to the place where the file was found, while the Location is the path where it was actually loaded. For example, if the assembly was downloaded from the internet, its CodeBase may start with " http:// ", but its Location may start with " C:\“ . 如果文件是阴影复制的,那么Location将是shadow copy dir中文件副本的路径 . 知道CodeBase不能保证是最好的 . 在GAC中为程序集设置 . 但是,总是会为从磁盘加载的程序集设置位置 . “

    您可能希望使用CodeBase而不是Location .

  • -3

    这有帮助吗?

    //get the full location of the assembly with DaoTests in it
    string fullPath = System.Reflection.Assembly.GetAssembly(typeof(DaoTests)).Location;
    
    //get the folder that's in
    string theDirectory = Path.GetDirectoryName( fullPath );
    
  • 5

    我发现我的解决方案足以检索位置 .

    var executingAssembly = new FileInfo((Assembly.GetExecutingAssembly().Location)).Directory.FullName;
    
  • 2

    Web应用程序?

    Server.MapPath("~/MyDir/MyFile.ext")
    
  • 0
    string path = Path.GetDirectoryName(typeof(DaoTests).Module.FullyQualifiedName);
    
  • 1

    如果路径包含“#”符号,您将获得不正确的目录 . 所以我使用了John Sibly答案的修改,即UriBuilder.Path和UriBuilder.Fragment的组合:

    public static string AssemblyDirectory
    {
        get
        {
            string codeBase = Assembly.GetExecutingAssembly().CodeBase;
            UriBuilder uri = new UriBuilder(codeBase);
            //modification of the John Sibly answer    
            string path = Uri.UnescapeDataString(uri.Path.Replace("/", "\\") + 
              uri.Fragment.Replace("/", "\\"));
            return Path.GetDirectoryName(path);
         }
    }
    
  • 11

    这应该有效,除非程序集是阴影复制的:

    string path = System.Reflection.Assembly.GetExecutingAssembly().Location
    
  • 6

    这些年来,没有人真正提到这一个 . 我从令人敬畏的ApprovalTests project中学到了一个技巧 . 诀窍是您使用程序集中的调试信息来查找原始目录 .

    This will not work in RELEASE mode, nor with optimizations enabled, nor on a machine different from the one it was compiled on.

    但这会让你的路径 relative to the location of the source code file you call it from

    public static class PathUtilities
    {
        public static string GetAdjacentFile(string relativePath)
        {
            return GetDirectoryForCaller(1) + relativePath;
        }
        public static string GetDirectoryForCaller()
        {
            return GetDirectoryForCaller(1);
        }
    
    
        public static string GetDirectoryForCaller(int callerStackDepth)
        {
            var stackFrame = new StackTrace(true).GetFrame(callerStackDepth + 1);
            return GetDirectoryForStackFrame(stackFrame);
        }
    
        public static string GetDirectoryForStackFrame(StackFrame stackFrame)
        {
            return new FileInfo(stackFrame.GetFileName()).Directory.FullName + Path.DirectorySeparatorChar;
        }
    }
    
  • 31

    我在过去的 NUnit 中有相同的行为 . 默认情况下 NUnit 将程序集复制到临时目录中 . 您可以在 NUnit 设置中更改此行为:

    enter image description here

    也许 TestDriven.NETMbUnit GUI具有相同的设置 .

  • 7

    使用CodeBase和UNC Network共享时唯一有效的解决方案是:

    System.IO.Path.GetDirectoryName(new System.Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath);
    

    它也适用于普通的URI .

  • 6

    那这个呢:

    System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
    
  • 0

    这是John Sibly代码的VB.NET端口 . Visual Basic不区分大小写,因此他的几个变量名称与类型名称冲突 .

    Public Shared ReadOnly Property AssemblyDirectory() As String
        Get
            Dim codeBase As String = Assembly.GetExecutingAssembly().CodeBase
            Dim uriBuilder As New UriBuilder(codeBase)
            Dim assemblyPath As String = Uri.UnescapeDataString(uriBuilder.Path)
            Return Path.GetDirectoryName(assemblyPath)
        End Get
    End Property
    
  • -2

    这个怎么样 ...

    string ThisdllDirectory = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
    

    然后只是砍掉你不需要的东西

  • 2

    我怀疑这里真正的问题是你的测试运行器正在将你的程序集复制到另一个位置 . 在运行时无法确定程序集的复制位置,但您可以翻转一个开关,告诉测试运行程序从何处运行程序集,而不是将其复制到影子目录 .

    当然,对于每个测试跑步者来说,这种切换可能是不同的 .

    您是否考虑将XML数据作为资源嵌入测试程序集中?

  • 290

    您存在的当前目录 .

    Environment.CurrentDirectory;  // This is the current directory of your application
    

    如果您使用build复制.xml文件,您应该找到它 .

    要么

    System.Reflection.Assembly assembly = System.Reflection.Assembly.GetAssembly(typeof(SomeObject));
    
    // The location of the Assembly
    assembly.Location;
    

相关问题