|
.NET TIPS
Win32エラー・コードからエラー・メッセージを取得するには?[C#、VB]
デジタルアドバンテージ 一色 政彦
2008/05/15 |
|
|
「TIPS:Win32 APIのWin32エラー・コードを取得するには?」では、Win32エラー・コードを取得する方法を紹介した。取得したWin32エラー・コードの中には、それに対応するエラー・メッセージが存在する場合がある(※存在しない場合もある)。コード番号だけではエラーの意味がよく分からないことが多いだろうが、エラー・メッセージを提示すればそれがエラーを解消する助けとなることもあるだろう。
そこで本稿ではエラー・メッセージを取得する方法について紹介する。
エラー・メッセージを取得するには?
Win32エラー・コードからエラー・メッセージを取得するには、FormatMessage関数(Win32 API)を利用すればよい。実際にこの関数を.NETのコードで利用するには、まずは次のような定義を行う。
[DllImport("kernel32.dll")]
static extern uint FormatMessage(
uint dwFlags, IntPtr lpSource,
uint dwMessageId, uint dwLanguageId,
StringBuilder lpBuffer, int nSize,
IntPtr Arguments); |
<DllImport("Kernel32.dll")> _
Public Function FormatMessage( _
ByVal dwFlags As Integer, ByRef lpSource As IntPtr, _
ByVal dwMessageId As Integer, ByVal dwLanguageId As Integer, _
ByVal lpBuffer As StringBuilder, ByVal nSize As Integer, _
ByRef Arguments As IntPtr) As Integer
End Function |
|
エラー・メッセージを取得するFormatMessage関数の定義(上:C#、下:VB) |
第1引数のdwFlagsにはメッセージの出力オプションを指定する。本稿の例では、次の出力オプションを指定する。これはシステムからメッセージを取得するというオプションである。
private const uint FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000; |
Private Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000 |
|
本TIPSで使用するメッセージの出力オプション(上:C#、下:VB) |
第2引数のlpSourceには、メッセージが定義されている場所(=ソース)を指定するが、ここでは限定しないことを意味する「IntPtr.Zero」(=0)を指定する。
第3引数のdwMessageIdには(前掲のTIPSで取得した)Win32エラー・コードを指定する。
第4引数のdwLanguageIdには言語識別子を指定するが、ここでは特定の言語に依存しないことを示す「0」を指定する。
第5引数のlpBufferには文字列バッファを、第6引数のnSizeにはその文字列バッファに格納できる文字数を指定する。本TIPSでは、255文字分の文字列バッファを持つStringBuilderクラス(System.Text名前空間)のオブジェクト作成して第5引数に指定し、第6引数にはそのStringBuilderオブジェクトに格納できる文字数を返すCapacityプロパティの値を指定する。
第6引数のArgumentsはメッセージをカスタマイズするときに使うが、本TIPSでは使用しないので「IntPtr.Zero」(=0)を指定する。
それではFormatMessage関数を使った実際のサンプル・コードを示そう。次のコードは、「TIPS:Win32 APIのWin32エラー・コードを取得するには?」で示したサンプル・プログラムを拡張したものである。追記したのは太字の部分で、そこでFormatMessage関数を使ってWin32エラー・メッセージを取得してコンソールに出力している。
using System;
using System.Runtime.InteropServices;
using System.Text;
class BeepProgram {
[DllImport("kernel32.dll", SetLastError = true)]
private extern static bool Beep(uint dwFreq, uint dwDuration);
[DllImport("kernel32.dll")]
static extern uint FormatMessage(
uint dwFlags, IntPtr lpSource,
uint dwMessageId, uint dwLanguageId,
StringBuilder lpBuffer, int nSize,
IntPtr Arguments);
private const uint FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
private static void Main() {
bool ret = Beep(0x8000, 500);
if (ret == false) {
// エラーが発生
int errCode = Marshal.GetLastWin32Error();
Console.WriteLine("Win32エラー・コード:" +
String.Format("{0:X8}", errCode));
StringBuilder message = new StringBuilder(255);
FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM,
IntPtr.Zero,
(uint)errCode,
0,
message,
message.Capacity,
IntPtr.Zero);
Console.WriteLine("Win32エラー・メッセージ:" +
message.ToString());
// 出力結果:
// Win32エラー・メッセージ:パラメータが間違っています。
}
}
} |
Imports System.Runtime.InteropServices
Imports System.Text
Module BeepProgram
<DllImport("kernel32.dll", SetLastError:=True)> _
Private Function Beep _
(ByVal dwFreq As Integer, ByVal dwDuration As Integer) As Boolean
End Function
<DllImport("Kernel32.dll")> _
Public Function FormatMessage( _
ByVal dwFlags As Integer, ByRef lpSource As IntPtr, _
ByVal dwMessageId As Integer, ByVal dwLanguageId As Integer, _
ByVal lpBuffer As StringBuilder, ByVal nSize As Integer, _
ByRef Arguments As IntPtr) As Integer
End Function
Private Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000
Sub Main()
Dim ret As Boolean = Beep(&H8000, 500)
If ret = False Then
' エラーが発生
Dim errCode As Integer = Marshal.GetLastWin32Error()
Console.WriteLine("Win32エラー・コード:" & _
String.Format("{0:X8}", errCode))
Dim message As New StringBuilder(255)
FormatMessage( _
FORMAT_MESSAGE_FROM_SYSTEM, _
IntPtr.Zero, _
errCode, _
0, _
message, _
message.Capacity, _
IntPtr.Zero)
Console.WriteLine("Win32エラー・メッセージ:" & _
message.ToString())
' 出力結果:
' Win32エラー・メッセージ:パラメータが間違っています。
End If
End Sub
End Module |
|
Win32エラー・コードからエラー・メッセージを取得するサンプル・プログラム(上:C#、下:VB) |
このサンプル・プログラムの場合では「パラメータが間違っています。」というエラー・メッセージが表示される。これは、開発者にとって問題を解決するヒントになるだろう。なお、実際にはBeep関数の第1引数(パラメータ)に指定している(16進数で)「8000」という数値が範囲外のためエラーが発生している。
|
generated by
|
|
Insider.NET 記事ランキング
本日
月間