vb.net AccessViolationException 和 FatalExecutionEngineError
vb.net AccessViolationException and FatalExecutionEngineError
我已经在这个项目上工作了大约一个星期,在本周初,我的 ReadFile 返回了一个 AccessViolationException - "Attempted to read or write protected memory." 所以我稍微研究了一下它就消失了.我以为我修好了但也许没有?现在我的 WriteFile 抛出一个 FatalExecutionEngineError,经过一些阅读后似乎这两个事件可能是相关的;不过我不确定。这是我的声明,这些声明可能有问题:
<DllImport("kernel32.dll")> Private Shared Function CloseHandle(
ByVal hObject As Integer) As Integer
End Function
<DllImport("kernel32.dll")> Private Shared Function CreateFile(
<MarshalAs(UnmanagedType.LPStr)> ByVal lpFileName As String,
ByVal dwDesiredAccess As Integer, ByVal dwShareMode As Integer,
ByVal lpSecurityAttributes As Integer,
ByVal dwCreationDisposition As Integer,
ByVal dwFlagsAndAttributes As Integer,
ByVal hTemplateFile As Integer) As Integer
End Function
<DllImport("kernel32.dll")> Private Shared Function GetCommState(
ByVal hCommDev As Integer, ByRef lpDCB As DCB) As Integer
End Function
<DllImport("kernel32.dll")> Private Shared Function GetCommTimeouts(
ByVal hFile As Integer, ByRef lpCommTimeouts As COMMTIMEOUTS) As Integer
End Function
<DllImport("kernel32.dll")> Private Shared Function GetLastError() As Integer
End Function
<DllImport("kernel32.dll")> Private Shared Function PurgeComm(
ByVal hFile As Integer, ByVal dwFlags As Integer) As Integer
End Function
<DllImport("kernel32.dll")> Private Shared Function ReadFile(
ByVal hFile As Integer, ByVal Buffer As Byte(),
ByVal nNumberOfBytesToRead As Integer,
ByRef lpNumberOfBytesRead As Integer,
ByRef lpOverlapped As Overlapped) As Integer
End Function
<DllImport("kernel32.dll")> Private Shared Function SetCommTimeouts(
ByVal hFile As Integer, ByRef lpCommTimeouts As COMMTIMEOUTS) As Integer
End Function
<DllImport("kernel32.dll")> Private Shared Function SetCommState(
ByVal hCommDev As Integer, ByRef lpDCB As DCB) As Integer
End Function
<DllImport("kernel32.dll")> Private Shared Function WriteFile(
ByVal hFile As Integer, ByVal Buffer As Byte(),
ByVal nNumberOfBytesToWrite As Integer,
ByRef lpNumberOfBytesWritten As Integer,
ByRef lpOverlapped As Overlapped) As Integer
End Function
<DllImport("kernel32.dll")> Private Shared Function SetCommMask(
ByVal hFile As Integer,
ByVal dwEvtMask As Integer) As Integer
End Function
<DllImport("kernel32.dll", SetLastError:=True)> Private Shared Function WaitCommEvent(
ByVal hFile As Integer,
ByRef mask As Integer,
ByRef lpOverlap As Overlapped) As Integer
End Function
<DllImport("kernel32.dll")> Private Shared Function FormatMessage(
ByVal dwFlags As Integer,
ByVal lpSource As Integer,
ByVal dwMessageId As Integer,
ByVal dwLanguageId As Integer,
ByVal lpBuffer As StringBuilder,
ByVal nSize As Integer,
ByVal Arguments As Integer) As Integer
End Function
这里是最初导致 AccessViolationException 的代码,它消失了:
Private Function read() As String
Dim sErrTxt As String
Dim iReadChars, iRc As Integer
If mhRS <> INVALID_HANDLE_VALUE Then
' Sets Comm Mask
iRc = SetCommMask(mhRS, EventMasks.RxChar)
If iRc <> 0 Then
'Waits for a comm event
iRc = WaitCommEvent(mhRS, miEvtMask, Nothing)
If iRc <> 0 Then
miStringSize = 0
miString = ""
ReDim mabtRxBuf(miBufferSize)
' Loop through the buffer and store it in a string while there is still chars in the buffer
For i As Integer = 0 To 20
iRc = ReadFile(mhRS, mabtRxBuf, miBufferSize, iReadChars, Nothing)
If iRc <> 0 Then
' Stores the size of the string read and forms the string
If iReadChars > 0 Then
miStringSize += iReadChars
miString &= defaultEncoding.GetString(mabtRxBuf)
End If
Else
' Read Error
sErrTxt = pErr2Text(GetLastError())
MsgBox("ReadFile failed " & sErrTxt)
Return Nothing
End If
Next
'Loop While iReadChars > 0
' Returns the concantenated string
Return miString
Else
' Handles WaitCommEvent error
sErrTxt = pErr2Text(GetLastError())
MsgBox("WaitCommEvent failed " & sErrTxt)
Return Nothing
End If
Else
' Handles SetSommMask error
sErrTxt = pErr2Text(GetLastError())
MsgBox("Unable to SetCommMask " & sErrTxt)
Return Nothing
End If
Else
' Handles port not open error
MsgBox("Please initialize port first")
Return Nothing
End If
End Function
最后,这是导致 FatalExecutionEngineError 的代码:
Private Sub write(ByVal byteBuff As Byte())
Dim sErrTxt As String
Dim bytesSent = 0, iRc, iWriteChars As Integer
If mhRS <> INVALID_HANDLE_VALUE Then
' Writes the passed Byte() to the comm port
iRc = WriteFile(mhRS, byteBuff, byteBuff.Length, iWriteChars, Nothing)
If iRc = 0 Then
' Handles WriteFile error
sErrTxt = pErr2Text(GetLastError())
MsgBox("WriteFile Failed " & sErrTxt)
End If
Else
' Handles port not open error
MsgBox("Please initialize port first")
Exit Sub
End If
End Sub
我在 windows 7 64 位上使用 visual studio 2015 和 .NET 4.6.1。我重新安装了 .net,但没有用,所以我将应用程序转移到另一台机器上,看它是否可以在那里工作,但没有。第二台机器与第一台相同。我不知道从这里去哪里。
最终为我解决的代码:
Private receivedText As String
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
With miPort
.PortName = "COM3"
.BaudRate = 38400
.Parity = Parity.None
.StopBits = StopBits.One
.DataBits = 8
.DtrEnable = True
.RtsEnable = True
.Handshake = Handshake.None
.Encoding = Encoding.GetEncoding(28591)
End With
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If Not miPort.IsOpen Then
miPort.Open()
End If
If miPort.IsOpen Then
miPort.Write(toCharacters("55FF0510030004BC0105010189D1"))
End If
End Sub
' Converts the passed string as hexidecimal numbers to its characters
Private Function toCharacters(ByVal hexText As String) As String
Dim num As String
Dim sendText As String = ""
For y As Integer = 1 To Len(hexText) Step 2
' Takes two of the numbers passed (1 byte in Hex)
num = Mid(hexText, y, 2)
' Converts the numbers into their decimal number, then to their character and stores them in a String()
sendText &= (ChrW(Val("&h" & num)))
Next y
Return sendText
End Function
Private Sub miPort_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles miPort.DataReceived
receivedText = miPort.ReadExisting()
End Sub
我已经在这个项目上工作了大约一个星期,在本周初,我的 ReadFile 返回了一个 AccessViolationException - "Attempted to read or write protected memory." 所以我稍微研究了一下它就消失了.我以为我修好了但也许没有?现在我的 WriteFile 抛出一个 FatalExecutionEngineError,经过一些阅读后似乎这两个事件可能是相关的;不过我不确定。这是我的声明,这些声明可能有问题:
<DllImport("kernel32.dll")> Private Shared Function CloseHandle(
ByVal hObject As Integer) As Integer
End Function
<DllImport("kernel32.dll")> Private Shared Function CreateFile(
<MarshalAs(UnmanagedType.LPStr)> ByVal lpFileName As String,
ByVal dwDesiredAccess As Integer, ByVal dwShareMode As Integer,
ByVal lpSecurityAttributes As Integer,
ByVal dwCreationDisposition As Integer,
ByVal dwFlagsAndAttributes As Integer,
ByVal hTemplateFile As Integer) As Integer
End Function
<DllImport("kernel32.dll")> Private Shared Function GetCommState(
ByVal hCommDev As Integer, ByRef lpDCB As DCB) As Integer
End Function
<DllImport("kernel32.dll")> Private Shared Function GetCommTimeouts(
ByVal hFile As Integer, ByRef lpCommTimeouts As COMMTIMEOUTS) As Integer
End Function
<DllImport("kernel32.dll")> Private Shared Function GetLastError() As Integer
End Function
<DllImport("kernel32.dll")> Private Shared Function PurgeComm(
ByVal hFile As Integer, ByVal dwFlags As Integer) As Integer
End Function
<DllImport("kernel32.dll")> Private Shared Function ReadFile(
ByVal hFile As Integer, ByVal Buffer As Byte(),
ByVal nNumberOfBytesToRead As Integer,
ByRef lpNumberOfBytesRead As Integer,
ByRef lpOverlapped As Overlapped) As Integer
End Function
<DllImport("kernel32.dll")> Private Shared Function SetCommTimeouts(
ByVal hFile As Integer, ByRef lpCommTimeouts As COMMTIMEOUTS) As Integer
End Function
<DllImport("kernel32.dll")> Private Shared Function SetCommState(
ByVal hCommDev As Integer, ByRef lpDCB As DCB) As Integer
End Function
<DllImport("kernel32.dll")> Private Shared Function WriteFile(
ByVal hFile As Integer, ByVal Buffer As Byte(),
ByVal nNumberOfBytesToWrite As Integer,
ByRef lpNumberOfBytesWritten As Integer,
ByRef lpOverlapped As Overlapped) As Integer
End Function
<DllImport("kernel32.dll")> Private Shared Function SetCommMask(
ByVal hFile As Integer,
ByVal dwEvtMask As Integer) As Integer
End Function
<DllImport("kernel32.dll", SetLastError:=True)> Private Shared Function WaitCommEvent(
ByVal hFile As Integer,
ByRef mask As Integer,
ByRef lpOverlap As Overlapped) As Integer
End Function
<DllImport("kernel32.dll")> Private Shared Function FormatMessage(
ByVal dwFlags As Integer,
ByVal lpSource As Integer,
ByVal dwMessageId As Integer,
ByVal dwLanguageId As Integer,
ByVal lpBuffer As StringBuilder,
ByVal nSize As Integer,
ByVal Arguments As Integer) As Integer
End Function
这里是最初导致 AccessViolationException 的代码,它消失了:
Private Function read() As String
Dim sErrTxt As String
Dim iReadChars, iRc As Integer
If mhRS <> INVALID_HANDLE_VALUE Then
' Sets Comm Mask
iRc = SetCommMask(mhRS, EventMasks.RxChar)
If iRc <> 0 Then
'Waits for a comm event
iRc = WaitCommEvent(mhRS, miEvtMask, Nothing)
If iRc <> 0 Then
miStringSize = 0
miString = ""
ReDim mabtRxBuf(miBufferSize)
' Loop through the buffer and store it in a string while there is still chars in the buffer
For i As Integer = 0 To 20
iRc = ReadFile(mhRS, mabtRxBuf, miBufferSize, iReadChars, Nothing)
If iRc <> 0 Then
' Stores the size of the string read and forms the string
If iReadChars > 0 Then
miStringSize += iReadChars
miString &= defaultEncoding.GetString(mabtRxBuf)
End If
Else
' Read Error
sErrTxt = pErr2Text(GetLastError())
MsgBox("ReadFile failed " & sErrTxt)
Return Nothing
End If
Next
'Loop While iReadChars > 0
' Returns the concantenated string
Return miString
Else
' Handles WaitCommEvent error
sErrTxt = pErr2Text(GetLastError())
MsgBox("WaitCommEvent failed " & sErrTxt)
Return Nothing
End If
Else
' Handles SetSommMask error
sErrTxt = pErr2Text(GetLastError())
MsgBox("Unable to SetCommMask " & sErrTxt)
Return Nothing
End If
Else
' Handles port not open error
MsgBox("Please initialize port first")
Return Nothing
End If
End Function
最后,这是导致 FatalExecutionEngineError 的代码:
Private Sub write(ByVal byteBuff As Byte())
Dim sErrTxt As String
Dim bytesSent = 0, iRc, iWriteChars As Integer
If mhRS <> INVALID_HANDLE_VALUE Then
' Writes the passed Byte() to the comm port
iRc = WriteFile(mhRS, byteBuff, byteBuff.Length, iWriteChars, Nothing)
If iRc = 0 Then
' Handles WriteFile error
sErrTxt = pErr2Text(GetLastError())
MsgBox("WriteFile Failed " & sErrTxt)
End If
Else
' Handles port not open error
MsgBox("Please initialize port first")
Exit Sub
End If
End Sub
我在 windows 7 64 位上使用 visual studio 2015 和 .NET 4.6.1。我重新安装了 .net,但没有用,所以我将应用程序转移到另一台机器上,看它是否可以在那里工作,但没有。第二台机器与第一台相同。我不知道从这里去哪里。
最终为我解决的代码:
Private receivedText As String
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
With miPort
.PortName = "COM3"
.BaudRate = 38400
.Parity = Parity.None
.StopBits = StopBits.One
.DataBits = 8
.DtrEnable = True
.RtsEnable = True
.Handshake = Handshake.None
.Encoding = Encoding.GetEncoding(28591)
End With
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If Not miPort.IsOpen Then
miPort.Open()
End If
If miPort.IsOpen Then
miPort.Write(toCharacters("55FF0510030004BC0105010189D1"))
End If
End Sub
' Converts the passed string as hexidecimal numbers to its characters
Private Function toCharacters(ByVal hexText As String) As String
Dim num As String
Dim sendText As String = ""
For y As Integer = 1 To Len(hexText) Step 2
' Takes two of the numbers passed (1 byte in Hex)
num = Mid(hexText, y, 2)
' Converts the numbers into their decimal number, then to their character and stores them in a String()
sendText &= (ChrW(Val("&h" & num)))
Next y
Return sendText
End Function
Private Sub miPort_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles miPort.DataReceived
receivedText = miPort.ReadExisting()
End Sub