【问题标题】:Finding exe/dll path that works in single exe and running through "dotnet <program.dll>"查找在单个 exe 中运行并通过 \"dotnet <program.dll>\" 运行的 exe/dll 路径
【发布时间】:2023-01-05 03:26:41
【问题描述】:

有没有办法获取当前 exe 或 dll 的位置,无论我们是从独立的 exe 运行还是从 dotnet 调用?

Environment.ProcessPath 适用于单个文件 exe,但如果使用“dotnet <program.dll>”调用程序,则它会返回安装 dotnet 运行时的文件夹。

System.Reflection.Assembly.GetEntryAssembly().Location 适用于从 dotnet 调用,但不适用于单个文件 exe。

有没有对两者都适用的方法?我能否检测到我处于一种情况或另一种情况并基于此调用正确的方法?

【问题讨论】:

  • “获取位置”:AppContext.BaseDirectory 返回的不是这个吗?

标签: c# .net-7.0


【解决方案1】:

单文件部署和可执行文档提到some Assembly APIs will not work in this mode,包括Location,它将返回一个空字符串:

API Note
Assembly.CodeBase Throws System.PlatformNotSupportedException.
Assembly.EscapedCodeBase Throws System.PlatformNotSupportedException.
Assembly.GetFile Throws System.IO.IOException.
Assembly.GetFiles Throws System.IO.IOException.
Assembly.Location Returns an empty string.
AssemblyName.CodeBase Returns null.
AssemblyName.EscapedCodeBase Returns null.
Module.FullyQualifiedName Returns a string with the value of &lt;Unknown&gt; or throws an exception.
Marshal.GetHINSTANCE Returns -1.
Module.Name Returns a string with the value of &lt;Unknown&gt;.

提到了一些解决方法:

  • 要访问可执行文件旁边的文件,请使用System.AppContext.BaseDirectory

  • 要查找可执行文件的文件名,请使用 System.Environment.GetCommandLineArgs 的第一个元素,或者从 .NET 6 开始,使用 System.Environment.ProcessPath 中的文件名。

  • 为避免完全运送松散的文件,请考虑使用嵌入式资源。

因此,根据此信息,您可以使用 System.Reflection.Assembly.GetEntryAssembly().Location,如果它是空字符串 - 使用 Environment.ProcessPath 或仅使用 Environment.GetCommandLineArgs()[0]

来自Environment.GetCommandLineArgs remarks

数组中的第一个元素包含正在执行的程序的文件名。如果文件名不可用,则第一个元素等于 String.Empty。其余元素包含在命令行中输入的任何其他标记。

在 .NET 5 及更高版本中,对于单文件发布,第一个元素是主机可执行文件的名称。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-07
    • 1970-01-01
    • 1970-01-01
    • 2014-04-02
    • 1970-01-01
    • 2019-02-22
    • 2015-09-30
    • 1970-01-01
    相关资源
    最近更新 更多