从.NET设置特定的COM HRESULT值

mar*_*c_s 2 c# com exception-handling com-interop hresult

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

大多数东西工作正常 - 我现在正在调整我的错误处理.

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

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

我有我自己的自定义.NET异常类,我知道我可以HResult在基ApplicationException类上设置受保护的属性- 但不知怎的,我无法设法获取我的"前缀"加上我的错误代码才能工作....

使用系统;

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

无论我在这里尝试什么 - 我只是无法得到一个代表存储到我的基类中的int值(for base.HResult,which is a int)0x888803E9...

我在这里失踪了什么?

Han*_*ant 6

C#编译器只是麻烦你阻止你绊倒溢出bug.理所当然,很多这种代码都无法在溢出检查中生存,而不是你在错误处理代码中想要的那种不幸事件:)注意upvoted答案中的代码如何通过Project> Properties> Build> Advanced>"Check for算术溢出/下溢"选项勾选.一个没有得到充分利用的选项.

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

  base.HResult = unchecked((int)(0x88880000U + errorCode));
Run Code Online (Sandbox Code Playgroud)

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

  const int ErrorBase = unchecked((int)0x88880000);
  base.HResult = ErrorBase + errorCode;
Run Code Online (Sandbox Code Playgroud)

令人难以忍受的是:您生成的HRESULT不是有效的,它没有正确的设施代码.该代码提供了错误来自的提示.Interop代码应使用0x80040000作为错误基础来选择FACILITY_ITF.不太确定你会对0x88880000感到悲伤,但是你生成的消息字符串是最重要的.不幸的是,客户端代码中往往会跳过ISupportErrorInfo,因此没有任何人真正看到它的绝佳保证.