Установка конкретного значения COM HRESULT из.NET

Я создаю сборку.NET, которая должна быть вызываемой COM, например, из 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;
    }
}

Неважно, что я пытаюсь здесь - я просто не могу получить int значение (для base.HResult, который является int) который представляет 0x888803E9 храниться в моем базовом классе...

Что мне здесь не хватает??

2 ответа

Решение

Компилятор 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, как правило, пропускается в клиентском коде, поэтому нет большой гарантии, что кто-нибудь его увидит.

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.

Другие вопросы по тегам