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

有没有办法获得当前代码所在的程序集的path? 我不想要调用程序集的path,只是包含代码的path。

基本上我的unit testing需要读取一些相对于dll的xmltesting文件。 我希望path始终正确parsing,无论testingdll是从TestDriven.NET,MbUnit GUI还是其他的运行。

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

我的testing库位于说

C:\项目\ MyApplication的\ daotests \ BIN \debugging\ daotests.dll

我想得到这个path:

C:\项目\ MyApplication的\ daotests \ BIN \debugging\

当我从MbUnit Gui运行时,到目前为止的三个build议都失败了:

  • 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给出与以前相同。

我已经定义了以下属性,因为我们经常在unit testing中使用它。

 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属性有时会给出一些有趣的结果,所以我更喜欢使用以URI格式给出path的CodeBase ,然后UriBuild.UnescapeDataStringFile:// at开始,并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; 

和约翰的答案一样,但稍微less了一些冗长的扩展方法。

 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共享的唯一解决scheme是:

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

我怀疑这里真正的问题是你的testing者正在将你的程序集复制到不同的位置。 在运行时没有办法知道程序集是从哪里复制的,但是您可能会翻转一个开关,告诉testing运行程序从它的位置运行程序集,而不是将其复制到阴影目录。

当然,这样的转换对于每个testing运行者来说可能是不同的。

你有没有考虑在testing程序集中embedded你的XML数据作为资源?

 AppDomain.CurrentDomain.BaseDirectory 

与MbUnit GUI一起使用。

这里是John Sibly的代码的VB.NET端口。 Visual Basic不区分大小写,所以他的一些variables名称与types名称相冲突。

 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 

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

 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是find文件的地址,而Location是实际加载的path,例如,如果程序集是从网上下载的,CodeBase可能以“http://”开头, ,但是它的位置可能以“C:\”开始,如果该文件被影子拷贝了,位置就是影子副本目录中文件拷贝的path,也很好的知道CodeBase不能被保证要在GAC中为程序集设置,但是始终会为从磁盘加载的程序集设置位置。

可能想要使用CodeBase代替位置。

当前存在的目录。

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

如果您使用build来复制.xml文件,您应该可以find它。

要么

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

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

为基于磁盘(而不是基于Web),非GAC组件的正确方法是使用当前正在执行的程序集的CodeBase属性。

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

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

这么多年来,没有人提到过这个。 我从美妙的ApprovalTests项目中学到了一招。 诀窍是您使用程序集中的debugging信息来查找原始目录。

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

但是这会得到相对于你调用它的源代码文件位置的path

 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; } } 
 var assembly = System.Reflection.Assembly.GetExecutingAssembly(); var assemblyPath = assembly.GetFiles()[0].Name; var assemblyDir = System.IO.Path.GetDirectoryName(assemblyPath); 
 string path = Path.GetDirectoryName(typeof(DaoTests).Module.FullyQualifiedName); 

您可以通过AppDomain.CurrentDomain.RelativeSearchPath获取binpath

这个怎么样 …

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

然后就干掉你不需要的东西

这是我想出来的。 在Web项目之间,unit testing(nunit和resharpertesting运行器) ; 我发现这对我有用。

我一直在寻找代码来检测构build的是什么样的configuration, Debug/Release/CustomName 。 唉, #if DEBUG所以如果有人能改善这一点

随意编辑和改进。

获取应用文件夹 。 有用的网站,unittests获取testing文件的文件夹。

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

获取bin文件夹 :用于使用reflection执行程序集。 如果由于构build属性而在那里复制文件。

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

这应该工作:

 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文件库以及一些configuration文件(这是从DLL文件中使用log4net)。

我发现我的解决scheme足以找回位置。

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

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

在这里输入图像描述

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

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

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

我已经写了一个完整的描述,如何做到这一点在一个DLL里面二 – http://nodogmablog.bryanhogan.net/2016/09/locating-and-checking-an-executing-dll-on-a-running-web -服务器/

我用这个来获取Bin目录的path:

 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”

Web应用程序?

 Server.MapPath("~/MyDir/MyFile.ext")