【问题标题】:Catching COMException specific Error Code捕获 COMException 特定的错误代码
【发布时间】:2020-03-27 10:26:20
【问题描述】:

我希望有人可以帮助我。我有一个来自 COM 的特定异常,我需要捕获它然后尝试做其他事情,所有其他的都应该被忽略。我的异常错误消息是:

System.Runtime.InteropServices.COMException (0x800A03EC):Microsoft Office Excel 无法访问文件“C:\test.xls”。 有几个可能的原因:

所以我最初的尝试是

try
{
 // something
}
catch (COMException ce)
{
   if (ce.ErrorCode == 0x800A03EC)
   {
      // try something else 
   }
}

然后我读到了编译器警告:

警告 22 与积分比较 常数是无用的;常数是 超出类型范围 'int' .....ExcelReader.cs 629 21

现在我知道 0x800A03EC 是 HResult,我刚刚在 MSDN 上看过 并阅读:

HRESULT 是一个 32 位的值, 分为三个不同的领域: 严重性代码、设施代码和 错误代码。严重性代码 表示是否返回值 表示信息、警告或 错误。设施代码标识 负责的系统区域 错误。

所以我的最终问题是,我如何确保捕获该特定异常?或者如何从 HResult 中获取错误代码?

提前致谢。

【问题讨论】:

  • 只是为了添加注释。重现此异常并不容易,因为我需要一个非常具体的配置来做到这一点,我正在努力,但我认为在这里询问可能会更快:)

标签: c# com


【解决方案1】:

ErrorCode 应该是一个无符号整数;您可以按如下方式进行比较:

try {
    // something
} catch (COMException ce) {
    if ((uint)ce.ErrorCode == 0x800A03EC) {
        // try something else 
    }
}

【讨论】:

  • 所以,从 C# 代码中,没有办法像 using WinErrorsOrWhatever 然后 if ((uint)ce.ErrorCode == E_UNEXPECTED_OR_WHATEVER)
  • 上述方法有效,但仅在 unchecked 上下文中编译时有效。否则,否定的ce.ErrorCode 不会愉快地转换为肯定的uint。实际上,将== 符号的另一侧转换为if (ce.ErrorCode == unchecked((int)0x800A03EC)) { ... } 会更好。见an example on MSDN
  • 那么这是一个框架错误吗? Exception.HResult 是否应该定义为 uint?
  • @Tristan:我认为它是这样声明的,因为无符号类型不符合 CLS。
  • 上面评论的更新的工作链接:docs.microsoft.com/en-us/dotnet/api/system.exception.hresult
【解决方案2】:

HRESULT 值有 32 位,分为三个字段:严重性代码、设施代码和错误代码。严重性代码指示返回值是表示信息、警告还是错误。 设施代码标识了系统中导致错误的区域。 错误代码 是一个唯一编号,用于表示异常。每个异常都映射到不同的 HRESULT。 摘自:http://en.wikipedia.org/wiki/HRESULT

据我所知,HRESULT 位的前半部分可能会根据导致异常的系统/进程而改变。后半部分包含错误类型。

代码应如下所示:

try {
    // something
} catch (COMException ce) {
    if ((uint)ce.ErrorCode & 0x0000FFFF == 0x800A03EC) {
        // try something else 
    }
}

注意:请记住,我不是 .NET 专家,因此请注意上述代码中的语法错误。

【讨论】:

  • +1 :感谢您提供详细的细分。这是很久以前的东西,但对其他感兴趣的人很有用。
  • & 0x0000FFFF 有什么用?它将“删除”(设置为 0)uint 的左半部分,所以它永远不会是 == 0x800A03EC,对吧?
【解决方案3】:

我实际上设法让它在我需要的系统上运行,发现错误代码是 -2146807284。

这样看,如果我把 0x800A03EC 转换成 Binary,然后把它当作 2 的补码,就可以计算出值了。

【讨论】:

  • 是的,替代方法是将 HRESULT 转换为有符号整数,但可能保留十六进制代码使其更具可读性(并且更易于 google)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-10
  • 1970-01-01
  • 2014-04-26
  • 1970-01-01
  • 2020-10-08
  • 2013-02-16
相关资源
最近更新 更多