Last API error message...

Merrion

Well-known member
Joined
Sep 29, 2001
Messages
265
Location
Dublin, Ireland
User Rank
*Experts*
I am trying to get the last API error message thus:-
Code:
    Public Enum Format_Message_Flags
        FORMAT_MESSAGE_ALLOCATE_BUFFER = &H100
        FORMAT_MESSAGE_IGNORE_INSERTS = &H200
        FORMAT_MESSAGE_FROM_STRING = &H400
        FORMAT_MESSAGE_FROM_HMODULE = &H800
        FORMAT_MESSAGE_FROM_SYSTEM = &H1000
        FORMAT_MESSAGE_ARGUMENT_ARRAY = &H2000
    End Enum

    <DllImport("kernel32.dll", EntryPoint:="FormatMessageA", _
     CharSet:=CharSet.Ansi, _
     ExactSpelling:=True, _
     CallingConvention:=CallingConvention.StdCall)> _
    Private Function FormatMessage(ByVal dwFlags As Format_Message_Flags, ByVal lpSource As Int32, ByVal dwMessageId As Int32, ByVal dwLanguageId As Int32, ByVal lpBuffer As String, ByVal nSize As Int32, ByVal Arguments As Int32) As Int32

    End Function

   Public Function GetAPIErrorMessageDescription(ByVal ApiErrNumber As Int32) As String

        Dim sError As New String("", MAX_MESSAGE_LENGTH)
        Dim lErrorMessageLength As Int32

        lErrorMessageLength = FormatMessage(Format_Message_Flags.FORMAT_MESSAGE_FROM_SYSTEM, 0, ApiErrNumber, 0, sError, MAX_MESSAGE_LENGTH, 0)
        If lErrorMessageLength > 0 Then
            sError.Substring(0, lErrorMessageLength)
        End If

        GetAPIErrorMessageDescription = sError

    End Function

But lErrorMessageLength seems to always return 0? I am using Windows XP.

Thanks in advance,
Duncan
 
You need to set dwLanguageId to &H0.
Code:
Private Declare Unicode Sub SetLastError Lib "kernel32" ( _
    ByVal dwErrCode As Int32)
Private Declare Unicode Function GetLastError Lib "kernel32" () As Int32
Private Declare Ansi Function FormatMessage Lib "kernel32" Alias "FormatMessageA" ( _
    ByVal dwFlags As Int32, _
    ByVal lpSource As Int32, _
    ByVal dwMessageId As Int32, _
    ByVal dwLanguageId As Int32, _
    ByVal lpBuffer As StringBuilder, _
    ByVal nSize As Int32, _
    ByVal Arguments As Int32) As Int32

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
    SetLastError(1)

    Dim sBuffer As New StringBuilder(512)
    Dim iReturn As Int32

    iReturn = FormatMessage(&H1000, 0, GetLastError(), &H0, sBuffer, sBuffer.Capacity, 0)
    If iReturn Then
        MessageBox.Show(sBuffer.ToString, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information)
    Else
        MessageBox.Show("FormatMessage failed to return an error string.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error)
    End If
End Sub
I also changed the declaration to use the StringBuilder class instead. It seems to be a bit more capable.
[edit]&H0 is the value of LANG_NEUTRAL.[/edit]
 
Last edited by a moderator:
Back
Top