【问题标题】:Setting specific COM HRESULT value from .NET从 .NET 设置特定的 COM HRESULT 值
【发布时间】:2015-10-02 23:56:39
【问题描述】:

我正在创建一个 .NET 程序集,该程序集需要可从例如 COM 调用。 VB6等

大多数东西都可以正常工作 - 我现在正在微调我的错误处理。

我想做的是为我的异常创建特定的 HRESULT 值 - 例如对于我的异常情况,请使用 0x88880001 等值。 我想使用一个通用的“前缀”(例如0x8888),然后将我的内部错误代码(从十进制的 1001 向上运行)添加到该数字。

所以我的内部错误 1001 应该变成 HRESULT = 0x888803E9 等等。

我有自己的自定义 .NET 异常类,我知道我可以在基础 ApplicationException 类上设置受保护的 HResult 属性 - 但不知何故我无法获得我的“前缀”加上我的错误代码上班……

使用系统;

public class CustomException : ApplicationException
{
    public CustomException(string message, int errorCode) : base(message)
    {
        base.HResult = (uint) 0x88880000 + errorCode;
    }
}

无论我在这里尝试什么 - 我都无法将代表0x888803E9int 值(对于base.HResult,这是一个int)存储到我的基类中......

我在这里错过了什么??

【问题讨论】:

    标签: c# exception-handling com com-interop hresult


    【解决方案1】:

    C# 编译器只是麻烦您阻止您触发溢出错误。可以说,很多此类代码无法在溢出检查中幸存下来,而不是您在错误处理代码中想要的那种事故:) 请注意,被赞成的答案中的代码如何与 Project > Properties > Build > Advanced > “Check for算术上溢/下溢”选项打勾。一个没有被充分使用的选项。

    您必须使用 unchecked 关键字来禁止此运行时检查:

      base.HResult = unchecked((int)(0x88880000U + errorCode));
    

    或者你可以在编译时抑制它:

      const int ErrorBase = unchecked((int)0x88880000);
      base.HResult = ErrorBase + errorCode;
    

    令人痛苦的是:您将生成的 HRESULT 不是有效的,它没有正确的设施代码。该代码提供了错误来自何处的提示。互操作代码应使用 0x80040000 作为选择 FACILITY_ITF 的错误基础。不过,不太确定您是否会对 0x88880000 感到悲伤,但您生成的消息字符串是最重要的。不幸的是,ISupportErrorInfo 往往会在客户端代码中被跳过,因此不能很好地保证任何人都能看到它。

    【讨论】:

    • 谢谢,这似乎可以解决问题 - 无论项目设置如何! :-) 不敢相信默认情况下设置是 OFF,在 C# 项目中......
    • VB 默认开启。不幸的是,溢出检查非常昂贵,损失很大。
    【解决方案2】:
    base.HResult = (int)((uint)0x88880000 + errorCode);
    

    base.HResult 是一个 System.Int32。

    但是,您的数字大于 Int32,因此它会翻转。不确定您需要什么以及checked 是否有帮助。

    但是,这似乎检查了:

    void Main()
    {
        var ce = new CustomException("uh oh", 1001);
        Console.WriteLine(ce.HResult);
        // Convert integer as a hex in a string variable
        string hexValue = ce.HResult.ToString("X");
        // Convert the hex string back to the number
        int decAgain = int.Parse(hexValue, System.Globalization.NumberStyles.HexNumber);        
        Console.WriteLine(hexValue);
        Console.WriteLine(decAgain);
    }
    
    
    public class CustomException : Exception
    {
        public CustomException(string message, int errorCode) : base(message)
        {
            base.HResult = (int)((uint)0x88880000 + errorCode);
        }
    }
    

    最佳实践是所有异常都从 Exception 类派生。

    【讨论】:

    • 你试过这个代码吗?它会在(int)((uint)0x88880000 + errorCode) 上抛出一个OverflowException
    • 不在 LINQPad 中。也许您正在使用带有@Hans Passant 描述的设置的VS
    猜你喜欢
    • 2021-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-25
    • 2011-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多