【问题标题】:Assembly CodeBase Gives Wrong Location汇编代码库给出了错误的位置
【发布时间】:2018-02-02 19:46:45
【问题描述】:

我正在使用 ExcelDna 编写一个 Excel 插件。我想找到安装程序集的目录,以便我可以从该目录打开文件。我过去曾成功使用过这种方法,但升级到 .NET Framework 4.7.1 后它就不起作用了。我正在尝试找出原因。

这是我的插件中当前的内容:

var codePath = Assembly.GetExecutingAssembly().CodeBase;

当我在调试器中将鼠标悬停在它上面时,它会给出正确的路径。在我执行语句codePath 后,有 mscorlib 的位置(并且使用调试器将鼠标悬停在它上面仍然有正确的位置)。我也尝试过使用typeof(<typeWithNoIneritance>).Assembly.CodeBase 和使用Location 而不是CodeBase 的变体。

接下来我应该看什么?

更新 问题可能不是 .NET Framework 更新,而是我同时进行的 ExcelDna 更新。它正在从无法提供文件位置信息的字节数组中加载文件。我能够禁用它,它现在正在工作。

【问题讨论】:

标签: c# reflection


【解决方案1】:

更新

在进一步挖掘之后(参见 cmets 的答案),看起来 Excel 或任何在运行时加载插件的机制正在使用 Assembly.Load 方法,该方法采用 byte[] 而不是文件。 (换句话说,它首先将程序集作为byte[] 加载到内存中,然后将其加载到AppDomain 中)。因此,.NET 运行时实际上并不知道文件位置,因此将为.Location (doc) 返回一个空字符串,或者为.CodeBase (doc) 返回一个调用者的代码库。

不幸的是,这意味着没有一个很好的方法可以通过反射来确定文件的来源。

上一个答案

听起来您的代码正在获取JIT inline optimized,所以我会尝试将查找拉入一个单独的方法并添加一个属性来指示 CLR 不要内联该方法。

    [MethodImpl(MethodImplOptions.NoInlining)]
    public string GetLocation()
    {
        return this.GetType().Assembly.Location;
    }

如果您正在寻找包含该行代码的程序集的路径,您将需要使用

this.GetType().Assembly.Location

有关CodeBaseAssembly 之间区别的更多信息,请查看https://blogs.msdn.microsoft.com/suzcook/2003/06/26/assembly-codebase-vs-assembly-location/

【讨论】:

  • 我试过这个。这给了我在描述中提到的 mscorlib。
  • @tyson 听起来 JIT 内联是你的问题。查看我的更新答案
  • 感谢您的建议。我尝试过这个。现在我得到一个空字符串。
  • this.GetType().Assembly.FullName 得到什么?
  • 我发现有一个名为“LoadFromBytes”的选项设置为 true。现在我已经禁用了它,它似乎可以工作。我回头一看,意识到我在更新框架的同时更新了 ExcelDna。如果您想更新您的答案,我会接受它作为解决方案。感谢您的帮助。
【解决方案2】:

请改用Assembly.Location

var codePath = Assembly.GetExecutingAssembly().Location;

CodeBase 是指向文件所在位置的 URL,而 Location 是实际加载文件的路径。

引用自here

【讨论】:

  • 这不是关于是否使用CodeBaseLocation 的问题,因为我在描述中提到过这两种方法。我可以解析网址。这是一个关于为什么我得到 mscorlib 而不是我的程序集的问题。
  • 啊,我的错。我的猜测是,正在执行的程序集不是您的程序集。那我会试试约翰的回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多