如何获取代码所在程序集的路径?
Posted
技术标签:
【中文标题】如何获取代码所在程序集的路径?【英文标题】:How do I get the path of the assembly the code is in? 【发布时间】:2021-11-14 19:56:34 【问题描述】:有没有办法获取当前代码所在程序集的路径?我不想要调用程序集的路径,只想要包含代码的路径。
基本上我的单元测试需要读取一些与 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 和
设置\乔治\本地
Settings\Temp\ ....\DaoTests.dll
System.Reflection.Assembly.GetExecutingAssembly().Location
给出的和前面的一样。
【问题讨论】:
这是您的解决方案:var dir = AppDomain.CurrentDomain.BaseDirectory; 这应该是公认的解决方案。 AppDomain.CurrentDomain.BaseDirectory 是正确的方法。 查看相关:finding-my-main-executables-path-using-assembly-vs-appdomain 我来这里是为了寻找一个解决方案,让一个 nuget 包从它的 pacakge 目录中读取一个 JSON 文件。似乎当执行 nuget 包时,“AppDomain.CurrentDomain.BaseDirectory”指向正在运行的项目目录,而不是 nuget 包目录。这些似乎都没有正确定位 nuget 包目录。 @Lucas 不,它不会因为这不是这个问题的目的(事实上,当它被问到时,nuget 并不存在) - 随意开始一个新问题并在那里联系我但我现在可以告诉你,在大多数情况下这是不可能的。对于大多数项目,nuget 目录是 sln 文件旁边的packages
。 但是 当你编译和分发东西时,没有 sln 文件,也没有包目录。在编译期间,需要的东西(但不是所有东西)都被复制到 bin 目录中。最好的办法是使用 postbuild 脚本来复制你想要的文件。
【参考方案1】:
我定义了以下属性,因为我们经常在单元测试中使用它。
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 中的目录和文件名中允许使用数字符号。【参考方案2】:这有帮助吗?
//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 );
【讨论】:
将xml文件设置为内容,用dll复制,或者资源,从dll读取。 或者只是typeof(DaoTests).Assembly
我个人会采用这样的方法:public static string GetAssemblyDirectory<T>()return System.IO.Path.GetDirectoryName(typeof(T).Assembly.Location);
@SLaks @JohnySkovdal @Keith:大家好,使用Assembly.GetExecutingAssembly()
。它“获取包含当前正在执行的代码的程序集”(来自方法描述)。我在我的插件“EntitiesToDTOs”中使用它。实例见AssemblyHelper.cs。
@John Silby 的帖子有问题,因为它看起来不适用于 UNC 路径...例如\\服务器\文件夹\文件.ext。这个成功了。 +1【参考方案3】:
就这么简单:
var dir = AppDomain.CurrentDomain.BaseDirectory;
【讨论】:
这应该是公认的解决方案。 AppDomain.CurrentDomain.BaseDirectory 是正确的方法。 感谢您让我的注意力重新回到这一点 - 不确定在我提出问题时是否可用,但现在可用。 不,这是错误的。这将返回原始入口点的路径,而不是当前执行的代码。如果您从不同的路径手动加载程序集,或者从 GAC 加载程序集,它将返回错误的结果。这个答案是正确的:***.com/a/283917/243557 更快的是Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
。
实际上这在 Web 应用程序中不起作用,但据我发现,以下增强应该适用于任何类型的应用程序:AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory
如果您只想获取测试程序集的原始 bin 路径(例如,访问子文件夹中的辅助数据文件),这对于单元测试非常有用。测试程序集是代码的入口点。【参考方案4】:
与 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 指出的那样,您传入了一个参数但没有使用它。
这个答案对于手头的问题是完全错误的。此答案的修改版本可以为您提供给定程序集的路径。但是,在这里,我们专门寻找正在执行的程序集,因此传入程序集是没有意义的。扩展方法是错误的工作工具。
你如何获得没有尾随bin/Debug/netcoreapp
等的位置?【参考方案5】:
在使用 CodeBase 和 UNC 网络共享时,唯一对我有用的解决方案是:
System.IO.Path.GetDirectoryName(new System.Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath);
它也适用于普通的 URI。
【讨论】:
这应该是公认的答案。默认代码库不能正确处理 UNC 共享,这真的很烦人。 当文件夹包含空格并且天知道还有什么其他字符时,这会崩溃...... 我一直在使用它并且发现 one 失败的场景:如果这行代码本身是 NuGet 包的一部分,然后由应用!我们也可以通过将GetExecutingAssembly()
替换为GetCallingAssembly()
来支持这种情况。
@Timo:您是否验证过此更改是否有副作用?如果是这样,请编辑答案以包含修复。
@IgnaciosolerGarcia 遗憾的是,我必须报告它只在一层深处工作,即如果 NuGet 包被另一个 NuGet 包调用,它会失败!我现在正在使用它(来自 Chernomordik 在此页面上的评论):AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory
。第一部分用于 Web 应用程序,第二部分用于其他应用程序。【参考方案6】:
这应该可以工作,除非程序集被影子复制:
string path = System.Reflection.Assembly.GetExecutingAssembly().Location
【讨论】:
【参考方案7】:我相信这适用于任何类型的应用程序:
AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory
【讨论】:
我的实验表明这是最万无一失的答案,不仅涵盖 Web 和控制台应用程序,还包括来自单元测试和 NuGet 包的调用(嵌套到任何级别的递归)。 感谢这个优雅的解决方案!【参考方案8】:这个呢:
System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
【讨论】:
不适用于 .net 5 捆绑程序集,请参阅 ***.com/a/62626131/2663813【参考方案9】:AppDomain.CurrentDomain.BaseDirectory
适用于 MbUnit GUI。
【讨论】:
这非常适合在 asp.net web 应用程序中写入相对于根目录的文件 我发现这个通常效果最好。如果您不确定,请选择它。 这是唯一正确的答案,所有其他答案都已弃用,并且在合并程序集时不起作用,因为位置将为空【参考方案10】:我怀疑这里真正的问题是您的测试运行程序正在将您的程序集复制到不同的位置。在运行时无法判断程序集是从哪里复制的,但您可能可以拨动一个开关来告诉测试运行程序从它所在的位置运行程序集,而不是将其复制到影子目录。
当然,对于每个测试运行者来说,这样的切换可能会有所不同。
您是否考虑过将您的 XML 数据作为资源嵌入到您的测试程序集中?
【讨论】:
+1 用于指出卷影复制的问题。不过确实可以从Assembly.CodeBase
中判断出原来的地方。【参考方案11】:
从 .net framework 4.6 / .net core 1.0 开始,现在有一个 AppContext.BaseDirectory,它应该给出与 AppDomain.CurrentDomain.BaseDirectory
相同的结果,除了 AppDomains 不是 .net core 1.x / 的一部分。 net 标准 1.x API。
AppContext.BaseDirectory
编辑:文档现在甚至声明:
在 .NET 5.0 及更高版本中,对于捆绑的程序集,返回的值是宿主可执行文件的包含目录。
确实,Assembly.Location doc 文档说:
在 .NET 5.0 及更高版本中,对于捆绑的程序集,返回的值为空字符串。
【讨论】:
【参考方案12】:这个怎么样……
string ThisdllDirectory = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
然后就砍掉你不需要的东西
【讨论】:
【参考方案13】:据我所知,其他大多数答案都有一些问题。
对disk-based (as opposed to web-based), non-GACed assembly 执行此操作的正确方法是使用当前正在执行的程序集的CodeBase
属性。
这将返回一个 URL (file://
)。与其乱用string manipulation 或UnescapeDataString
,不如利用Uri
的LocalPath
属性轻松转换。
var codeBaseUrl = Assembly.GetExecutingAssembly().CodeBase;
var filePathToCodeBase = new Uri(codeBaseUrl).LocalPath;
var directoryPath = Path.GetDirectoryName(filePathToCodeBase);
【讨论】:
如果路径包含#
则不起作用(EscapedCodeBase
有效,但如果路径包含例如 %20
逐字(这是 Windows 路径中允许的字符序列),则 EscapedCodeBase 不起作用/跨度>
如果我们想在 NuGet 包中包含此代码,我们可以通过将 GetExecutingAssembly()
替换为 GetCallingAssembly()
来解决这种情况。【参考方案14】:
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
var assemblyPath = assembly.GetFiles()[0].Name;
var assemblyDir = System.IO.Path.GetDirectoryName(assemblyPath);
【讨论】:
【参考方案15】:这是 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
【讨论】:
【参考方案16】:tl;博士
程序集和 DLL 文件的概念不同。根据程序集的加载方式,路径信息会丢失或根本不可用。 不过,在大多数情况下,提供的答案都会起作用。
这个问题和之前的答案存在一个误解。在大多数情况下,提供的答案可以正常工作,但 在某些情况下,不可能获取当前代码所在程序集的正确路径。
程序集(包含可执行代码)和 dll 文件(包含程序集)的概念不是紧密耦合的。大会可能 来自 DLL 文件,但不是必须的。
使用Assembly.Load(Byte[])
(MSDN) 方法,您可以直接从内存中的字节数组加载程序集。
字节数组来自哪里并不重要。它可以从文件中加载、从 Internet 下载、动态生成……
这是一个从字节数组加载程序集的示例。加载文件后路径信息会丢失。这是不可能的 获取原始文件路径,之前描述的所有方法都不起作用。
此方法位于执行程序集中,该程序集位于“D:/Software/DynamicAssemblyLoad/DynamicAssemblyLoad/bin/Debug/Runner.exe”
static void Main(string[] args)
var fileContent = File.ReadAllBytes(@"C:\Library.dll");
var assembly = Assembly.Load(fileContent);
// Call the method of the library using reflection
assembly
?.GetType("Library.LibraryClass")
?.GetMethod("PrintPath", BindingFlags.Public | BindingFlags.Static)
?.Invoke(null, null);
Console.WriteLine("Hello from Application:");
Console.WriteLine($"GetViaAssemblyCodeBase: GetViaAssemblyCodeBase(assembly)");
Console.WriteLine($"GetViaAssemblyLocation: assembly.Location");
Console.WriteLine($"GetViaAppDomain : AppDomain.CurrentDomain.BaseDirectory");
Console.ReadLine();
这个类位于Library.dll中:
public class LibraryClass
public static void PrintPath()
var assembly = Assembly.GetAssembly(typeof(LibraryClass));
Console.WriteLine("Hello from Library:");
Console.WriteLine($"GetViaAssemblyCodeBase: GetViaAssemblyCodeBase(assembly)");
Console.WriteLine($"GetViaAssemblyLocation: assembly.Location");
Console.WriteLine($"GetViaAppDomain : AppDomain.CurrentDomain.BaseDirectory");
为了完整起见,这里是 GetViaAssemblyCodeBase()
的实现,这对于两个程序集都是相同的:
private static string GetViaAssemblyCodeBase(Assembly assembly)
var codeBase = assembly.CodeBase;
var uri = new UriBuilder(codeBase);
return Uri.UnescapeDataString(uri.Path);
Runner 打印以下输出:
Hello from Library:
GetViaAssemblyCodeBase: D:/Software/DynamicAssemblyLoad/DynamicAssemblyLoad/bin/Debug/Runner.exe
GetViaAssemblyLocation:
GetViaAppDomain : D:\Software\DynamicAssemblyLoad\DynamicAssemblyLoad\bin\Debug\
Hello from Application:
GetViaAssemblyCodeBase: D:/Software/DynamicAssemblyLoad/DynamicAssemblyLoad/bin/Debug/Runner.exe
GetViaAssemblyLocation:
GetViaAppDomain : D:\Software\DynamicAssemblyLoad\DynamicAssemblyLoad\bin\Debug\
如您所见,代码库、位置或基目录都不正确。
【讨论】:
【参考方案17】:这些年来,实际上没有人提到这个。我从很棒的ApprovalTests project 中学到的一个技巧。诀窍是您使用程序集中的调试信息来查找原始目录。
这在 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;
【讨论】:
【参考方案18】:我一直在使用 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。
【讨论】:
@Kiquenet:这么多代码只是用于将 URI 转换为路径。当然可以改进。看看 Mike Schall 或 SoMoS 的答案。您不应尝试在字符串级别转换 URI,而应使用合适的对象。好吧,Assembly.CodeBase 返回一个字符串而不是一个更合适的对象,如 URI 或 FileInfo,也很笨拙。【参考方案19】:你所在的当前目录。
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;
【讨论】:
如果程序集已经是shadow copied,这将是有问题的。 +1520!如果您在 MSBuild 任务类中使用反射,Environment.CurrentDirectory
有效,其中执行程序集驻留在 GAC 中,而您的代码在其他地方。
一般而言,CurrentDirectory 不会告诉您可执行文件所在的位置。那不是它的用途。它只是经常与可执行文件所在的位置相同,因此很多程序员不理解其中的区别。然后,他们最终给一些希望应用程序理解正确使用 CurrentDirectory 的最终用户制造了麻烦。【参考方案20】:
您可以通过以下方式获取 bin 路径 AppDomain.CurrentDomain.RelativeSearchPath
【讨论】:
【参考方案21】:当开发人员可以更改代码以包含所需的 sn-p 时,所有建议的答案都有效,但如果您想在不更改任何代码的情况下执行此操作,则可以使用 Process Explorer。
它将列出系统上所有正在执行的 dll,您可能需要确定正在运行的应用程序的进程 ID,但这通常并不太难。
我已经写了关于如何在 II 中为 dll 执行此操作的完整描述 - http://nodogmablog.bryanhogan.net/2016/09/locating-and-checking-an-executing-dll-on-a-running-web-server/
【讨论】:
请注意,首先,本文中的代码是相当以 IIS 为中心的,其次,它为您提供(我相信)所有 当前加载的 dll,而不是正在运行的在任何时候。 给出的示例与 iis 相关,但如果 dll 在 iis 之外的进程中运行,则适用相同的步骤。这只是识别进程ID的问题。我会更新文章以说明这一点。感谢您的建议。【参考方案22】:在 Windows 窗体应用程序中,您可以简单地使用 Application.StartupPath
但对于 DLL 和控制台应用程序,代码更难记住...
string slash = Path.DirectorySeparatorChar.ToString();
string root = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
root += slash;
string settingsIni = root + "settings.ini"
【讨论】:
【参考方案23】:如果路径包含“#”符号,您将获得不正确的目录。 因此,我使用了对 John Sibly 答案的修改,即 UriBuilder.Path 和 UriBuilder.Fragment 的组合:
public static string AssemblyDirectory
get
string codeBase = Assembly.GetExecutingAssembly().CodeBase;
UriBuilder uri = new UriBuilder(codeBase);
//modification of the John Sibly answer
string path = Uri.UnescapeDataString(uri.Path.Replace("/", "\\") +
uri.Fragment.Replace("/", "\\"));
return Path.GetDirectoryName(path);
【讨论】:
【参考方案24】:对于 ASP.Net,它不起作用。我在Why AppDomain.CurrentDomain.BaseDirectory not contains "bin" in asp.net app? 找到了一个更好的解决方案。它适用于 Win 应用程序和 ASP.Net Web 应用程序。
public string ApplicationPath
get
if (String.IsNullOrEmpty(AppDomain.CurrentDomain.RelativeSearchPath))
return AppDomain.CurrentDomain.BaseDirectory; //exe folder for WinForms, Consoles, Windows Services
else
return AppDomain.CurrentDomain.RelativeSearchPath; //bin folder for Web Apps
【讨论】:
【参考方案25】:string path = Path.GetDirectoryName(typeof(DaoTests).Module.FullyQualifiedName);
【讨论】:
【参考方案26】:这就是我想出的。 在 web 项目之间,单元测试(nunit 和 resharper 测试运行器);我发现这对我有用。
我一直在寻找代码来检测构建的配置,Debug/Release/CustomName
。唉,#if DEBUG
。 如果有人可以改进它!
随意编辑和改进。
获取应用文件夹。用于 web 根目录,单元测试以获取测试文件的文件夹。
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 文件夹:对于使用反射执行程序集很有用。如果由于构建属性而将文件复制到那里。
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;
【讨论】:
【参考方案27】:这应该可行:
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 文件库以及一些配置文件(这是在 DLL 文件中使用 log4net)。
【讨论】:
这里fileMap
是干什么用的?【参考方案28】:
我发现我的解决方案足以检索位置。
var executingAssembly = new FileInfo((Assembly.GetExecutingAssembly().Location)).Directory.FullName;
【讨论】:
这已经是最受好评的答案之一了并且在问题中明确提到在这种情况下不起作用。 抱歉错过了!显然我没有仔细阅读。【参考方案29】:过去我在NUnit
中遇到了相同的行为。默认情况下NUnit
将您的程序集复制到临时目录中。您可以在NUnit
设置中更改此行为:
也许TestDriven.NET
和MbUnit
GUI 有相同的设置。
【讨论】:
【参考方案30】:我用它来获取 Bin 目录的路径:
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"
【讨论】:
我没有看到在这里避免使用 Path.getDirectoryName 的理由 @MaxKeller 如果你没有看到原因,并不意味着它是正确的。 Path.GetDirectoryName 的这种替代方法要快十倍。以上是关于如何获取代码所在程序集的路径?的主要内容,如果未能解决你的问题,请参考以下文章
背水一战 Windows 10 (122) - 其它: 通过 Windows.System.Profile 命名空间下的类获取信息, 查找指定类或接口的所在程序集的所有子类和子接口