Установка конкретного значения 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.