当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《如何获取代码所在的程序集路径?》经验,为你挑选了16个好方法。

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

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

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

我的测试库位于说

C:\项目\ MyApplication的\ daotests\BIN \调试\ daotests.dll

我想得到这条道路:

C:\项目\ MyApplication的\ daotests\BIN \调试\

当我从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 与前一个相同.

John Sibly.. 996

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

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格式.



1> John Sibly..:

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

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格式.


这有一个我遇到的问题,如果你的目录名是:c:\ My%20Directory那么Uri.UnescapeDataString将返回:c:\ My Directory这意味着File.Exists("c:\ My Directory\MyFile.txt ")将返回false,因为正确的路径实际上是"c:\ My%20Directory\MyFile.txt"我遇到了这个,因为我们的SVN路径中有空格,当我们检查它们时,它会对空格进行编码.
使用它来检查File.Exist()时要小心,因为此方法将在UNC路径上返回false.请改用@ Keith的答案.
注意:这不适用于网络位置(例如\\ REMOT_EPC\Folder)
如果目录中有数字符号'#',这也不起作用.Windows中的目录和文件名中允许使用数字符号.
不知道你可以在公众面前放静电.很高兴知道,我认为我更喜欢可读性
该死的,对我来说仍然无法工作:0(现在不是它给我MSBuild路径,我得到TeamCity C的路径:\ TeamCity\buildAgent\temp\buildTmp\SYSTEM_SVR1 2010-08-24 17_34_23\Out但是另一个获得路径的方式:-)
我已经使用这种方法很多年了,但是当有问题的目录路径包含一个“#”时,今天却失败了。

2> Keith..:

这有帮助吗?

//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 );


或者只是`typeof(DaoTests).Assembly`
@SLaks @JohnySkovdal @Keith:嘿伙计们,使用`Assembly.GetExecutingAssembly()`.它_"获取包含当前正在执行的代码的程序集"_(来自方法描述).我在我的AddIn"[EntitiesToDTOs](http://entitiestodtos.codeplex.com)"中使用它.有关实例,请参阅[AssemblyHelper.cs](https://entitiestodtos.svn.codeplex.com/svn/EntitiesToDTOs/EntitiesToDTOs/Helpers/AssemblyHelper.cs).
@John Silby的帖子有问题,因为它看起来不适用于UNC路径...例如\\ Server\Folder\File.ext.这个就行了.+1
将xml文件设置为内​​容,使用dll或资源进行复制,从dll中读取.

3> Jalal El-Sha..:

这很简单:

var dir = AppDomain.CurrentDomain.BaseDirectory;


不,这是错的.这将返回ORIGINAL ENTRY POINT的路径,而不是当前正在执行的代码.如果已从其他路径手动加载程序集,或者已从GAC加载程序集,则会返回错误的结果.这个答案是正确的:http://stackoverflow.com/a/283917/243557更快仍然是`Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)`.
这应该是公认的解决方案.AppDomain.CurrentDomain.BaseDirectory是正确的方法.
实际上这不适用于Web应用程序,但据我发现,以下扩充应适用于任何类型的应用程序:`AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory`
我希望原来的切入点如此完美
谢谢你把我的注意力还给了这个 - 不确定当我问这个问题时它是否可用,但现在是.
如果您只想获得测试装配的原始bin路径(例如,到达子文件夹中的辅助数据文件),这对于单元测试非常有用.测试程序集是代码的入口点.

4> Sneal..:

与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();


你的意思是'assembly`而不是`Assembly.GetExecutingAssembly()`?
对于手头的问题,这个答案是完全错误的.此答案的修改版本可以为您提供给定程序集的路径.但是,在这里,我们专门寻找正在执行的程序集,因此传入程序集是没有意义的.扩展方法是该作业的错误工具.
正如Dude指出的那样,你传递了一个论点并且未能使用它.

5> Ignacio Sole..:

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

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

它也适用于普通的URI.


这应该是公认的答案.默认代码库不能正确处理UNC共享真的很烦人.

6> jodonnell..:

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

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



7> huseyint..:

那这个呢:

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



8> Curt Hagenlo..:

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

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

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



9> 小智..:
AppDomain.CurrentDomain.BaseDirectory

适用于MbUnit GUI.



10> Mark Cidade..:
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
var assemblyPath = assembly.GetFiles()[0].Name;
var assemblyDir = System.IO.Path.GetDirectoryName(assemblyPath);



11> Mike Schall..:

这是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



12> spender..:

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

对基于磁盘(而不是基于Web)的非GACed程序集执行此操作的正确方法是使用当前正在执行的程序集的CodeBase属性.

这将返回一个URL(file://).而不是乱搞字符串操作,或者UnescapeDataString通过利用LocalPath属性来轻松转换Uri.

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



13> 小智..:

这个怎么样 ...

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

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



14> George Mauer..:

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

这不能在RELEASE模式下工作,也不能在启用优化的情况下工作,也不能在与编译它的机器不同的机器上工作.

但是这将获得相对于您调用它的源代码文件位置的路径

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;
    }
}



15> David Basara..:

您存在的当前目录.

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;


通常,CurrentDirectory不会告诉您可执行文件所在的位置.这不是它的用途.它恰好经常出现在可执行文件所在的位置,因此很多程序员都不了解其中的区别.然后他们最终为一些期望应用程序理解正确使用CurrentDirectory的最终用户造成麻烦.

16> dan gibson..:

我一直在使用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("/", "\\");

它一直在工作,但我不再确定它是100%正确的.http://blogs.msdn.com/suzcook/archive/2003/06/26/assembly-codebase-vs-assembly-location.aspx上的页面说:

"CodeBase是找到文件的地方的URL,而Location是实际加载的路径.例如,如果程序集是从Internet下载的,它的CodeBase可能以"http://"开头. ,但它的位置可能以"C:\"开头.如果文件是阴影复制的,则位置将是阴影副本目录中文件副本的路径.知道CodeBase不能得到保证也很好要为GAC中的程序集设置.但是,总是会为从磁盘加载的程序集设置位置. "

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

推荐阅读
重庆制造漫画社
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有