【问题标题】:Why would Assembly.GetExecutingAssembly() return null?为什么 Assembly.GetExecutingAssembly() 会返回 null?
【发布时间】:2011-01-23 11:32:35
【问题描述】:

我使用 xml 文件作为嵌入式资源来加载 XDocument。我们正在使用以下代码从程序集中获取适当的文件:

XDocument xd = new XDocument();
Assembly assembly = null;

try
{
    assembly = Assembly.GetExecutingAssembly();
}
catch(Exception ex)
{
    //Write exception to server event log
}

try
{
    if(assembly != null)
    {
        using(StreamReader sr = new 
            StreamReader(assembly.GetManifestResourceStream("assemblyPath")))
        {
            using(XmlTextReader xtr = new XmlTextReader(sr))
            {
                xd = XDocument.Load(xtr);
            }
        }
    }
}
catch(Exception ex)
{
    //Write exception to server event log
}

所以在部署代码时,我们偶尔会转到页面,并且不会从嵌入的文档中加载任何内容。当我们检查事件日志时,没有错误。如果用户只是刷新页面,它将正常加载。这让我想到,出于某种原因,assembly = Assembly.GetExecutingAssembly(); 偶尔会返回 null,而编写代码的方式并不是错误。所以,我的问题是为什么Assembly.GetExecutingAssembly(); 会返回null?我发现有几篇文章谈到有时非托管代码会出现错误,但这个应用程序是用 C# 编写并通过安装项目部署的。

该代码最初是在没有错误避免代码的情况下编写的。添加它是为了防止用户收到错误屏幕。异常会写入服务器的事件日志。

【问题讨论】:

  • 对不起,应该多指定一点。捕获正在调用实用程序项目中的方法以将异常写入事件日志。这样做的代码在整个应用程序中使用并且可以工作。另外,上面的代码是在页面初始化过程中调用的方法中。
  • 所以,在看到大家似乎都同意 GetExecutingAssembly() 不会返回 null 之后,我回去查看了剩下的方法。经过一番搜索,我在 MSDN 上找到了这篇文章:msdn.microsoft.com/en-us/library/xc4235zt(VS.85).aspx。如果找不到或无法访问资源,则表示 GetManifestResourceStream() 可以返回 null 。将 null 返回到 using() 构造不会导致异常。所以我们要部署它,看看它是否是罪魁祸首。
  • 我希望“部署”是指“使用测试服务器将测试版本部署到测试机器上”,并且您实际上并不是在为“冒烟测试”进行生产推送最后的评论似乎暗示。下次您的用户开始收到异常时,我建议您修复导致异常的错误,而不是仅仅取消通知。
  • “部署”是指它将经历另一个 QA 周期。到目前为止,这个问题只出现在生产代码中,所以我怀疑现在情况会改变。至于修复错误,这就是我现在正在尝试做的事情。
  • “添加它是为了防止用户收到错误屏幕” - 你是什么意思?你能不改变 app/web.config 让用户看不到这样的错误吗?有没有解决方案?

标签: c# assemblies embedded-resource system.reflection


【解决方案1】:

如果您尝试访问一个文件,请转到该文件,右键单击它,转到它的属性,将其 Build Action 更改为“Embedded Resource” ,然后确保您提供给“GetManifestResourceStream”的路径拼写正确。 可空性主要发生在路径/文件的拼写错误时。

【讨论】:

    【解决方案2】:

    如果您从非托管应用程序(例如 NUnit 测试运行器)启动代码,则可能返回 null:使用控制台尝试以下操作:

    [Test]
    public void att()
    {
        Assert.NotNull(Assembly.GetExecutingAssembly());
    }
    

    看到您已将其标记为嵌入,我猜您正在使用某种引导加载程序或解释器来运行您的 .Net 应用程序?这可能是非托管的(即不是 .Net 解释的),因此会返回 null。

    请参阅文档,“备注:http://msdn.microsoft.com/en-us/library/system.reflection.assembly.getentryassembly.aspx

    部分

    【讨论】:

    • 现在没有人会看它:/
    • 我做到了,我以为我要疯了,这是非常有用的谢谢。
    • 确实,GetEntryAssembly() 从非托管代码调用时可能会返回 null,但是 OP 询问 GetExecutingAssembly() 并且文档没有说明它返回 null。
    【解决方案3】:

    转到提及路径的文件的属性,并将 buildAction 从默认内容更改为 EmbeddedResource。重新编译,它应该可以工作。

    【讨论】:

      【解决方案4】:

      【讨论】:

        【解决方案5】:

        这是一个完美的例子,说明为什么吃异常是一个几乎普遍的坏主意,尤其是顶级System.Exception。问题可能在任何地方。很可能,真正的问题在于您的日志记录代码。

        取出那些空的catch 块(或用throw; 重新放入其中)并查看异常真正发生在哪里。一旦你找到真正的问题并重写你的代码,重写它以只捕获你真正知道如何处理的异常。

        GetExecutingAssembly 不会返回 null,句号。

        【讨论】:

          【解决方案6】:

          当遇到这样的情况时,我试图真正证明返回的值是空的。试试这个:

          try
          {
              assembly = Assembly.GetExecutingAssembly();
              Log.Write("Executing assembly is null: " + (assembly == null))
          }
          catch(Exception ex)
          {
              //Write exception to server event log
          }
          

          我怀疑它总是会写“假”,实际上是其他问题 - 可能是您的代码 sn-p 中没有包含的问题。

          【讨论】:

            猜你喜欢
            • 2013-08-09
            • 2013-06-05
            • 2014-05-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-01-15
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多