potisanのプログラミングメモ

趣味のプログラマーがプログラミング関係で気になったことや調べたことをいつでも忘れられるようにメモするブログです。はてなブログ無料版なので記事の上の方はたぶん広告です。記事中にも広告挿入されるみたいです。

C# Win32エラーコードをHRESULTへ変換する関数GetHRForWin32Error

動作確認環境:C# 8.0(.NET Core 3.1)、9.0(.NET 5.0)

Win32エラーコードをHRESULTへ変換する関数です。System.Runtime.InteropServices.MarshalクラスはDllImport属性の付いた関数の最終エラー(呼び出し直後のGetLastError関数の結果)からHRESULTへ変換する関数は提供しますが、それ以外のエラーからHRESULTへ変換する関数は提供しないので作成しました。Windows SDKHRESULT_FROM_WIN32マクロおよびインライン関数を参考にしています。

// using System.Runtime.CompilerServices;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static int GetHRForWin32Error(int x)
{
    const int FACILITY_WIN32 = 7;
    return x <= 0 ? x : (int)((x & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000);
}

サンプルコード

C# 9(トップレベルステートメント)

using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

const int ERROR_INSUFFICIENT_BUFFER = 122;

var hr = GetHRForWin32Error(ERROR_INSUFFICIENT_BUFFER);
Console.WriteLine(Marshal.GetExceptionForHR(hr).Message);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
static int GetHRForWin32Error(int x)
{
    const int FACILITY_WIN32 = 7;
    return x <= 0 ? x : (int)((x & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000);
}

参考