История кодов выхода и передовой опыт

История кодов выхода и передовой опыт

Я нахожу кучу повторяющихся кодов ошибок при установке и удалении Autodesk. Например

3010ERROR_SUCCESS_REBOOT_REQUIRED

-2147021886ERROR_SUCCESS_REBOOT_REQUIRED

и

1618ОШИБКА_УСТАНОВКИ_УЖЕ_ЗАПУСКАЕТСЯ

-2147023278ОШИБКА_УСТАНОВКИ_УЖЕ_ЗАПУСКАЕТСЯ

Мне интересно, является ли один или другой подход "более новым" или у Microsoft всегда были параллельные и избыточные коды выхода? И в любом случае, является ли один или другой подход предпочтительным? Я начинаю создавать свои собственные установщики и хочу быть уверенным, что использую правильную последовательность, если таковая имеется. Если нет лучшей практики, я чувствую, что положительные числа лучше, так как журналы короче.

решение1

В пользовательском режиме Windows коды ошибок используются в основном в двух формах. Одна из них —HRESULTи еще один -Коды ошибок Win32. HRESULT обычно используется вCOM-программированиеи указывается как значение HEX. Методы возвращают S_OK(ноль) после успеха, отрицательное значение в случае неудачи (начиная с 0x8). Коды ошибок Win32 — это целые числа в диапазоне от 0 до 65535 ( 2^16 - 1). Оба могут быть преобразованы друг в друга с помощью некоторых макросов, указанных в WinError.hзаголовочном файле в Windows SDK. Вот пример:

#define FACILITY_WIN32 7

#define __HRESULT_FROM_WIN32(x) \
((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : ((HRESULT) (((x) & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000)))

#define HRESULT_CODE(hr) ((hr) & 0xFFFF)

Для приведенного выше примера преобразование будет таким:

-2147021886 = 0x80070BC2 = (0x80070BC2 & 0xFFFF) = 0xBC2 = 3010
-2147023278 = 0x80070625 = (0x80070625 & 0xFFFF) = 0x652 = 1618

Оба этих кода ошибок определены в WinError.hзаголовочном файле. Если вы занимаетесь программированием COM, то используйте HRESULT (установщик часто использует COM). Если вы используете Win32 API, то используйте коды ошибок Win32 (возвращаемые GetLastError). Оба формата кодов ошибок можно передать для FormatMessage()получения эквивалентного сообщения об ошибке (как strerror()в мире Linux).

Дополнительные материалы для чтения:

решение2

Я бы сказал, что эти пары кодов выхода из ошибок представляют собой одни и те же ошибки:

$errCodes = 3010, -2147021886, 1618, -2147023278

foreach ($errCode in $errCodes) {
    '{0,12} 0x{1:x8}' -f $errCode, $errCode
}
        3010 0x00000bc2
 -2147021886 0x80070bc2
        1618 0x00000652
 -2147023278 0x80070652
foreach ($errCode in $errCodes) {
    '{0,12} 0x{1:x4}' -f $errCode, ($errCode -band 0xFFFF)
}
        3010 0x0bc2
 -2147021886 0x0bc2
        1618 0x0652
 -2147023278 0x0652

Связанный контент