Results 1 to 7 of 7

Thread: [RESOLVED] Exception Problems.

  1. #1

    Thread Starter
    Fanatic Member BlindSniper's Avatar
    Join Date
    Jan 2011
    Location
    South Africa
    Posts
    865

    Resolved [RESOLVED] Exception Problems.

    Hi all,
    I'm Creating a wrapper dll for my favorite Windows API functions. Normally when windows API calls fail, Nothing happens and you don't know why and this frustrates me. Although you can use their return value to determine If it was successful.

    My code (one example)
    vb.net Code:
    1. Public Function SetParent(ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As IntPtr
    2.         Dim result As IntPtr = Declarations.SetParent(hWndChild, hWndNewParent)
    3.         If result = IntPtr.Zero Then
    4.  
    5.             Dim ex As New System.ComponentModel.Win32Exception(Runtime.InteropServices.Marshal.GetLastWin32Error)
    6.            throw ex
    7.  
    8.  
    9.  
    10.         End If
    11.     End Function


    My problem is that when I create a new exception to be thrown I can't set the stack trace or other necessary information. I need to set this because when I just throw the exception the debugger will go to the line that threw the exception and Not the actual call.

    Any ideas ?

    EDIT: It seems like the only way is to create a custom exception. I don't want to do that since I like the Win32 exception.
    Last edited by BlindSniper; Apr 2nd, 2011 at 01:10 PM.

  2. #2
    Stack Overflow mod​erator
    Join Date
    May 2008
    Location
    British Columbia, Canada
    Posts
    2,824

    Re: Exception Problems.

    Add a
    Code:
    <DebuggerStepThrough()> _
    attribute on the line before your function.

  3. #3

    Thread Starter
    Fanatic Member BlindSniper's Avatar
    Join Date
    Jan 2011
    Location
    South Africa
    Posts
    865

    Re: Exception Problems.

    That is quite cool Thanks !

  4. #4
    Karen Payne MVP kareninstructor's Avatar
    Join Date
    Jun 2008
    Location
    Oregon
    Posts
    6,714

    Re: [RESOLVED] Exception Problems.

    Quote Originally Posted by BlindSniper View Post
    Hi all,
    Normally when windows API calls fail, Nothing happens and you don't know why and this frustrates me. Although you can use their return value to determine If it was successful.
    For a fully trusted application you can get both an error code and description for a failure of an API call shown below.


    Code:
    Imports System.Runtime.InteropServices
    Imports System.ComponentModel
    Public Class Form1
        Private Sub cmdTest_Click() Handles cmdTest.Click
            Console.WriteLine("Calling Win32 MessageBox without error...")
            Win32.MessageBox(New IntPtr(0), "Press OK...", "Press OK Dialog", 0)
    
            Dim ErrorCode As Integer = Marshal.GetLastWin32Error()
            If ErrorCode = 0 Then
                Console.WriteLine("1. Worked just fine")
            Else
                Dim ErrorMsg As New Win32Exception(ErrorCode)
                Console.WriteLine("1. The last Win32 Error was: {0} Description [{1}]", _
                                  ErrorCode, ErrorMsg.Message)
            End If
    
            ' Call the MessageBox with an invalid window handle to produce a Win32 error.
            Win32.MessageBox(New IntPtr(123132), "Press OK...", "Press OK Dialog", 0)
            ErrorCode = Marshal.GetLastWin32Error()
            If ErrorCode = 0 Then
                Console.WriteLine("2. Worked just fine")
            Else
                Dim ErrorMsg As New Win32Exception(ErrorCode)
                Console.WriteLine("2. The last Win32 Error was: {0} Description [{1}]", _
                                  ErrorCode, ErrorMsg.Message)
            End If
        End Sub
    End Class
    Code:
    Imports System.Runtime.InteropServices
    Module Win32
        ' Use DllImportAttribute to inport the Win32 MessageBox
        ' function.  Set the SetLastError flag to true to allow
        ' the function to set the Win32 error.
        <DllImportAttribute("user32.dll", _
                            SetLastError:=True, _
                            CharSet:=CharSet.Unicode)> _
        Function MessageBox( _
            ByVal hwnd As IntPtr, _
            ByVal text As String, _
            ByVal caption As String, _
            ByVal type As UInt32) As Integer
        End Function
        <DllImport("Kernel32.dll", _
                   EntryPoint:="FormatMessageW", _
                   SetLastError:=True, _
                   CharSet:=CharSet.Unicode, _
                   CallingConvention:=CallingConvention.StdCall)> _
        Public Function FormatMessage( _
            ByVal dwFlags As Integer, _
            ByRef lpSource As IntPtr, _
            ByVal dwMessageId As Integer, _
            ByVal dwLanguageId As Integer, _
            ByRef lpBuffer As String, _
            ByVal nSize As Integer, _
            ByRef Arguments As IntPtr) As Integer
        End Function
    End Module
    Output
    Code:
    Calling Win32 MessageBox without error...
    1. Worked just fine
    2. The last Win32 Error was: 1400 Description [Invalid window handle]

  5. #5
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Re: [RESOLVED] Exception Problems.

    Since it fits here any ways, same as kevin, a few functions to shorten it all. Import interopservices btw.

    Code:
        Public Shared Function HasError() As Boolean
            Return Marshal.GetLastWin32Error() <> 0
        End Function
        Public Shared Function LastError() As Exception
            Return New System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error())
        End Function
        <DebuggerStepThrough()> _
        Public Shared Sub HandleError()
            If HasError() Then Throw LastError
        End Sub
    
        Public Sub ThrowError(Optional ByVal location As String = "")
            Dim ex As New System.ComponentModel.Win32Exception(Runtime.InteropServices.Marshal.GetLastWin32Error())
            If ex.NativeErrorCode <> 0 Then MessageBox.Show(ex.Message, "Error at " & location, MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Sub
    
        Public Function GetLastError() As String
            Return New System.ComponentModel.Win32Exception(Runtime.InteropServices.Marshal.GetLastWin32Error()).Message
        End Function
    Code:
    'Error in an API right here
    ThrowError("Sending a message to my form.")
    MsgBox(GetLastError())
    HandleError()
    If HasError Then Throw LastError()

  6. #6
    Stack Overflow mod​erator
    Join Date
    May 2008
    Location
    British Columbia, Canada
    Posts
    2,824

    Re: [RESOLVED] Exception Problems.

    Quote Originally Posted by bergerkiller View Post
    Since it fits here any ways, same as kevin, a few functions to shorten it all. Import interopservices btw.

    Code:
        Public Shared Function HasError() As Boolean
            Return Marshal.GetLastWin32Error() <> 0
        End Function
        Public Shared Function LastError() As Exception
            Get
                Return New System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error())
                End If
            End Get
        End Function
    
        Public Sub ThrowError(Optional ByVal location As String = "")
            Dim ex As New System.ComponentModel.Win32Exception(Runtime.InteropServices.Marshal.GetLastWin32Error())
            If ex.NativeErrorCode <> 0 Then MessageBox.Show(ex.Message, "Error at " & location, MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Sub
    
        Public Function GetLastError() As String
            Return New System.ComponentModel.Win32Exception(Runtime.InteropServices.Marshal.GetLastWin32Error()).Message
        End Function
    I've corrected the errors in your syntax:
    Code:
        Public Shared Function HasError() As Boolean
            Return Marshal.GetLastWin32Error() <> 0
        End Function
    
        Public Shared ReadOnly Property LastError() As ComponentModel.Win32Exception
            Get
                Return New ComponentModel.Win32Exception(Marshal.GetLastWin32Error())
            End Get
        End Function
    
        Public Sub ThrowError(Optional ByVal location As String = "")
            Dim ex As ComponentModel.Win32Exception = LastError
            If ex.NativeErrorCode <> 0 Then MessageBox.Show(ex.Message, "Error at " & location, MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Sub
    
        Public Function GetLastError() As String
            Return LastError.Message
        End Function
    EDIT: I see you edited your post.
    Last edited by minitech; Apr 2nd, 2011 at 06:05 PM.

  7. #7
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Re: [RESOLVED] Exception Problems.

    Yep sorry, noticed the leftovers from the property->function change just as you did.
    Ow and the last two functions came from a separate class, thus the duplicate exception creation code.

    Made it all even shorter, all you have to do is call "HandleError" and it will bring you to where it is called if there is an error, and display the exception in the debugger:
    Code:
        'Error handling
        Private Shared LastError As Exception
        <DebuggerStepThrough()> _
        Public Shared Sub HandleError()
            If LastError IsNot Nothing Then
                Throw LastError
            ElseIf Marshal.GetLastWin32Error() <> 0 Then
                Throw New System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error())
            End If
        End Sub
    The LastError member allows you to specify a custom error in case the LastWin32Error is not set.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width