![]() |
Languages »
VB.NET »
HowTo
Intermediate
License: The Code Project Open License (CPOL)
Raising API exceptions from Visual Basic .NETBy Duncan Edwards JonesHow to raise API exceptions from Visual basic .NET. |
VB, Windows, .NET 1.0, Visual Studio, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
Although the .NET framework wraps up the majority of Windows API in an easy to use and safe framework, there are occasions when a direct call to the Windows API cannot be avoided. In such cases it is useful to be able to provide meaningful exceptions should any error occur in the API call.
When you declare an API function in VB.NET, you set the attribute SetsLastError to indicate that if an error occurs while calling that function it should set the last error for you. For example, the declaration of the API call MessageBeep would be declared as:
<DllImport("user32", EntryPoint:="MessageBeep", _
SetLastError:=True, _
CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function MessageBeep _
ByVal uType As Int32 ) As Boolean
End Function
According to the documentation for this function on MSDN this function returns non-zero on success and sets the last error on failure. The parameter uType only accepts certain values so passing an incorrect value will set this error value to 87 meaning that the parameter is incorrect.
In Visual Basic 5 or 6 the error used to be held in Err.LastDllError. In Visual Basic .NET this has been replaced by the GetLastWin32Error.
Imports System.Runtime.InteropServices
'\\ Print last api error number
Debug.Write(Marshal.GetLastWin32Error)
The Windows API has a function, FormatMessage that can be used to turn the number of the last error to a meaningful description. This is declared as:
<DllImport("kernel32.dll", EntryPoint:="FormatMessageA", _
CharSet:=CharSet.Ansi, _
ExactSpelling:=True, _
CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function FormatMessage( _
ByVal dwFlags As Format_Message_Flags, 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
End Function
and used as:
Imports System.Text
Private Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000
Private Const MAX_MESSAGE_LENGTH = 512
Private Function GetAPIErrorMessageDescription( _
ByVal ApiErrNumber As Int32) As String
Dim sError As New StringBuilder(MAX_MESSAGE_LENGTH)
Dim lErrorMessageLength AsInt32
lErrorMessageLength = _
FormatMessage(Format_Message_Flags.FORMAT_MESSAGE_FROM_SYSTEM, _
0, ApiErrNumber, 0, sError, sError.Capacity, 0)
If lErrorMessageLength > 0 Then
Return sError.ToString
End If
End Function
To be of use to the VB.NET Try..Catch..Finally syntax for error handling, this code must be wrapped up in a class that is derived from Exception.
Public Class ApiException
Inherits ApplicationException
And the New constructor is overridden to put the last system error in place of the base class' Message member:
Private msMessage As String
Public Sub New()
'\\ Get the error message from the last error from the windows API...
msMessage = GetAPIErrorMessageDescription(Marshal.GetLastWin32Error)
End Sub
Public Overrides ReadOnly Property Message() As String
Get
Return msMessage
End Get
End Property
You can now write wrappers for your API calls that raise ApiException. E.g.:
Public Sub ApiMessageBeep(ByVal uType As Int32)
If Not Messagebeep(uType) Then
Throw New ApiException
End If
End Sub
This article was originally published on the Merrion Computing website.
Imports System.Text
Imports System.Runtime.InteropServices
Public Class ApiException
Inherits ApplicationException
#Region "API Declarations"
<DllImport("kernel32.dll", EntryPoint:="FormatMessageA", _
CharSet:=CharSet.Ansi, _
ExactSpelling:=True, _
CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function FormatMessage( _
ByVal dwFlags As Format_Message_Flags, _
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
End Function
#End Region
#Region "Private members"
Private Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000
Private Const MAX_MESSAGE_LENGTH = 512
#End Region
#Region "Private member variables "
Private msFunctionName As String
Private msMessage As String
#End Region
Private Function GetAPIErrorMessageDescription(_
ByVal ApiErrNumber As Int32) As String
Dim sError As New StringBuilder(MAX_MESSAGE_LENGTH)
Dim lErrorMessageLength As Int32
lErrorMessageLength = _
FormatMessage(Format_Message_Flags.FORMAT_MESSAGE_FROM_SYSTEM,
0, ApiErrNumber, 0, sError, sError.Capacity, 0)
If lErrorMessageLength > 0 Then
Return sError.ToString
End If
End Function
Public Sub New(ByVal ErrNumber As Int32, ByVal FunctionName As String)
'\\ Get the error message from the windows API...
msMessage = GetAPIErrorMessageDescription(ErrNumber)
msFunctionName = FunctionName
End Sub
Public Sub New(ByVal ErrNumber As Int32)
'\\ Get the error message from the windows API...
msMessage = GetAPIErrorMessageDescription(ErrNumber)
End Sub
Public Sub New()
'\\ Get the error message from the last error from the windows API...
msMessage = GetAPIErrorMessageDescription(Marshal.GetLastWin32Error)
End Sub
Public Sub New(ByVal FunctionName As String)
'\\ Get the error message from the last error from the windows API...
msMessage = GetAPIErrorMessageDescription(Marshal.GetLastWin32Error)
msFunctionName = FunctionName
End Sub
Public ReadOnly Property FunctionName() As String
Get
Return msFunctionName
End Get
End Property
Public Overrides ReadOnly Property Message() As String
Get
Return msMessage
End Get
End Property
End Class
| You must Sign In to use this message board. | |||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 4 Mar 2003 Editor: Rinish Biju |
Copyright 2003 by Duncan Edwards Jones Everything else Copyright © CodeProject, 1999-2009 Web15 | Advertise on the Code Project |