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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/52797/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 10:06:07  来源:igfitidea点击:

How do I get the path of the assembly the code is in?

提问by George Mauer

Is there a way to get the path for the assembly in which the current code resides? I do not want the path of the calling assembly, just the one containing the code.

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

Basically my unit test needs to read some xml test files which are located relative to the dll. I want the path to always resolve correctly regardless of whether the testing dll is run from TestDriven.NET, the MbUnit GUI or something else.

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

Edit: People seem to be misunderstanding what I'm asking.

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

My test library is located in say

我的测试库位于 say

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

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

and I would like to get this path:

我想得到这条路径:

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

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

The three suggestions so far fail me when I run from the MbUnit Gui:

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

  • Environment.CurrentDirectorygives c:\Program Files\MbUnit

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

  • System.Reflection.Assembly.GetExecutingAssembly().Locationgives the same as the previous.

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

采纳答案by John Sibly

I've defined the following property as we use this often in 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);
    }
}

The Assembly.Locationproperty sometimes gives you some funny results when using NUnit (where assemblies run from a temporary folder), so I prefer to use CodeBasewhich gives you the path in URI format, then UriBuild.UnescapeDataStringremoves the File://at the beginning, and GetDirectoryNamechanges it to the normal windows format.

Assembly.Location使用 NUnit 时,该属性有时会给您一些有趣的结果(其中程序集从临时文件夹运行),因此我更喜欢使用CodeBasewhich 以 URI 格式为您提供路径,然后UriBuild.UnescapeDataString删除File://开头的 ,并将其GetDirectoryName更改为普通的 Windows 格式.

回答by jodonnell

This should work, unless the assembly is shadow copied:

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

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

回答by David Basarab

The current directory where you exist.

您所在的当前目录。

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

If you copy the .xml file out with build you should find it.

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

or

或者

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

// The location of the Assembly
assembly.Location;

回答by Keith

Does this help?

这有帮助吗?

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

回答by Mark Cidade

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

回答by Curt Hagenlocher

I suspect that the real issue here is that your test runner is copying your assembly to a different location. There's no way at runtime to tell where the assembly was copied from, but you can probably flip a switch to tell the test runner to run the assembly from where it is and not to copy it to a shadow directory.

我怀疑这里的真正问题是您的测试运行器正在将您的程序集复制到不同的位置。在运行时没有办法知道程序集是从哪里复制的,但是您可以拨动一个开关来告诉测试运行程序从它所在的位置运行程序集,而不是将它复制到影子目录。

Such a switch is likely to be different for each test runner, of course.

当然,对于每个测试运行器来说,这样的切换很可能是不同的。

Have you considered embedding your XML data as resources inside your test assembly?

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

回答by huseyint

What about this:

那这个呢:

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

回答by Jesse C. Slicer

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

回答by dan gibson

I've been using Assembly.CodeBase instead of 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("/", "\");

It's been working, but I'm no longer sure it is 100% correct. The page at http://blogs.msdn.com/suzcook/archive/2003/06/26/assembly-codebase-vs-assembly-location.aspxsays:

它一直在工作,但我不再确定它是 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:\". If the file was shadow-copied, the Location would be the path to the copy of the file in the shadow copy dir. It's also good to know that the CodeBase is not guaranteed to be set for assemblies in the GAC. Location will always be set for assemblies loaded from disk, however."

“CodeBase 是文件所在位置的 URL,而 Location 是它实际加载的路径。例如,如果程序集是从 Internet 下载的,其 CodeBase 可能以“http://”开头, 但它的位置可能以 "C:\" 开头。如果文件是卷影复制的,则位置将是卷影复制目录中文件副本的路径。知道代码库不保证也很好为 GAC 中的程序集设置。但是,始终为从磁盘加载的程序集设置位置。

You maywant to use CodeBase instead of Location.

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

回答by Mike Schall

Here is a VB.NET port of John Sibly's code. Visual Basic is not case sensitive, so a couple of his variable names were colliding with type names.

这是约翰·西伯利的代码的 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