Antoine.st Error Process in Api

How to retrieve Win32 Errors


  Declare Ansi Function GetFileAttributesX _
    Lib "Kernel32.dll" _
    Alias "GetFileAttributesA" _
  ( _
      ByVal lpFileName As String _
  ) As Integer

  <DllImport( _
    "Kernel32.dll", _
    CallingConvention:=CallingConvention.Winapi, _
    CharSet:=CharSet.Ansi, _
    ExactSpelling:=False, _
    SetLastError:=True _
  )> Public Shared Function GetFileAttributes( _
    ByVal lpFileName As String) As Integer
  End Function

  <DllImport( _
    "Kernel32.dll", _
    CallingConvention:=CallingConvention.Winapi, _
    CharSet:=CharSet.Ansi, _
    ExactSpelling:=False, _
    SetLastError:=True _
  )> Public Shared Function FormatMessage( _
    ByVal dwFlags As Integer, _
    ByVal lpSource As IntPtr, _
    ByVal dwMessageId As Integer, _
    ByVal dwLanguageId As Integer, _
    ByVal lpBuffer As StringBuilder, _
    ByVal nSize As Integer, _
    ByVal Arguments As IntPtr) As Integer
  End Function

  Public Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000
  Public Const LANG_USER_DEFAULT = &H10000

  Private Sub Button1_Click( _
    ByVal sender As System.Object, _
    ByVal e As System.EventArgs _
  ) Handles Button1.Click

    If GetFileAttributes("c:\boot.hoge") = -1 Then
      Dim msgBuffer As New StringBuilder(1024)
      Call FormatMessage( _
            FORMAT_MESSAGE_FROM_SYSTEM, _
            IntPtr.Zero, _
            Marshal.GetLastWin32Error(), _
            LANG_USER_DEFAULT, _
            msgBuffer, _
            msgBuffer.Capacity, _
            IntPtr.Zero)
      MsgBox(msgBuffer.ToString())
    End If

  End Sub

とまぁ、こんな感じで。長々書く必要はなかったかも。ポイントは SetLastError を True にしておくってだけですね。Declare で宣言した場合は、自動的に True になります。FormatMessage() に関しては完全におまけです。

あ、Err.LastDllError がそのまま (Declare のときも、DllImport のときも) 使えるんでやんの。というわけで、Marshal.GetLastWin32Error() は、C# 用ですね。