有没有办法获取当前代码所在的程序集的路径?我不想要调用程序集的路径,只需要包含代码的路径.
基本上我的单元测试需要读取一些相对于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格式.
我已经定义了以下属性,因为我们经常在单元测试中使用它.
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格式.
这有帮助吗?
//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 dir = AppDomain.CurrentDomain.BaseDirectory;
与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();
使用CodeBase和UNC Network共享时,唯一有效的解决方案是:
System.IO.Path.GetDirectoryName(new System.Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath);
它也适用于普通的URI.
除非程序集是阴影复制,否则这应该有效:
string path = System.Reflection.Assembly.GetExecutingAssembly().Location
那这个呢:
System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
我怀疑这里真正的问题是你的测试运行器正在将你的程序集复制到另一个位置.在运行时无法确定程序集的复制位置,但您可以翻转一个开关,告诉测试运行程序从何处运行程序集,而不是将其复制到影子目录.
当然,对于每个测试跑步者来说,这种切换可能是不同的.
您是否考虑将XML数据作为资源嵌入测试程序集中?
AppDomain.CurrentDomain.BaseDirectory
适用于MbUnit GUI.
var assembly = System.Reflection.Assembly.GetExecutingAssembly(); var assemblyPath = assembly.GetFiles()[0].Name; var assemblyDir = System.IO.Path.GetDirectoryName(assemblyPath);
这是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
据我所知,大多数其他答案都有一些问题.
对基于磁盘(而不是基于Web)的非GACed程序集执行此操作的正确方法是使用当前正在执行的程序集的CodeBase
属性.
这将返回一个URL(file://
).而不是乱搞字符串操作,或者UnescapeDataString
通过利用LocalPath
属性来轻松转换Uri
.
var codeBaseUrl = Assembly.GetExecutingAssembly().CodeBase; var filePathToCodeBase = new Uri(codeBaseUrl).LocalPath; var directoryPath = Path.GetDirectoryName(filePathToCodeBase);
这个怎么样 ...
string ThisdllDirectory = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
然后只是砍掉你不需要的东西
这些年来,没有人真正提到这一个.我从一个很棒的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; } }
您存在的当前目录.
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;
我一直在使用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.