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

时间:2020-03-05 18:50:19  来源:igfitidea点击:

有没有办法获取当前代码所在的程序集的路径?我不希望调用程序集的路径,而只是包含代码的路径。

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

编辑:人们似乎误解了我在问什么。

我的测试库位于

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与上一个相同。

解决方案

回答

这应该起作用,除非程序集被影子复制:

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

回答

我们所在的当前目录。

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

如果将.xml文件复制到build中,则应该找到它。

或者

System.Reflection.Assembly assembly = System.Reflection.Assembly.GetAssembly(typeof(SomeObject));

// The location of the Assembly
assembly.Location;

回答

这有帮助吗?

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

回答

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

回答

我怀疑这里的真正问题是测试运行程序将程序集复制到其他位置。在运行时无法知道从何处复制程序集,但是我们可以翻转开关以告诉测试运行程序从其原处运行程序集,而不要将其复制到影子目录。

当然,对于每个测试跑步者来说,这样的切换可能会有所不同。

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

回答

那这个呢:

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

回答

string path = Path.GetDirectoryName(typeof(DaoTests).Module.FullyQualifiedName);

回答

我一直在使用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:"开头。如果该文件是卷影复制的,则该位置将是卷影复制目录中文件副本的路径。
还很高兴知道,不能保证为GAC中的程序集设置CodeBase。但是,将始终为从磁盘加载的程序集设置位置。"

我们可能要使用CodeBase而不是Location。

回答

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

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

使用NUnit时,Assembly.Location属性有时会给我们一些有趣的结果(程序集从一个临时文件夹运行),所以我更喜欢使用CodeBase来提供URI格式的路径,然后删除UriBuild.UnescapeDataString即可。首先是" File://",而" GetDirectoryName"将其更改为常规Windows格式。

回答

这是John Sible的代码的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

回答

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

回答

就这么简单:

var dir = AppDomain.CurrentDomain.BaseDirectory;

回答

AppDomain.CurrentDomain.BaseDirectory

与MbUnit GUI一起使用。