GetTempFileName抛出' System.AccessViolationException' vb.net

时间:2015-03-27 16:13:11

标签: vb.net kernel32

我是VB新手,正在开发VB6到VB.net的迁移。有一个API调用会在临时文件名中附加前缀。

我已将dll添加为

<DllImport("kernel32")> _
Private Shared Function GetTempFileName(ByVal lpszPath As String, ByVal lpPrefixString As String, ByVal wUnique As Long, ByVal lpTempFileName As String) As Long
End Function

当我打电话给你时:

test = GetTempFileName(My.Application.Info.DirectoryPath, Prefix, 0, m_sTempfile)

它抛出异常:

An unhandled exception of type 'System.AccessViolationException' occurred in Forum.exe

Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

我尝试使用Path.GetTempFileName()但我可能需要执行多次操作以获取前缀为特定单词并位于特定位置的文件名。 我越过检查了值,它们不是坏数据。 我尝试了多种解决方案,但都没有奏效。 有人可以帮助吗?提前谢谢!

1 个答案:

答案 0 :(得分:2)

将Pinvoke声明移动到VB.NET时需要重写它们。许多差异,比如Long需要整数,如果winapi函数返回一个字符串,那么你需要使用StringBuilder而不是String。必需,因为String是不可变类型。

适当的声明是:

<DllImport("kernel32", SetLastError:=True, CharSet:=CharSet.Auto)> _
Public Shared Function GetTempFileName(ByVal lpszPath As String, _
                                       ByVal lpPrefixString As String, _
                                       ByVal wUnique As Integer, _
                                       ByVal lpTempFileName As StringBuilder) As Integer
End Function

正确的电话看起来像:

    Dim buffer As New StringBuilder(260)
    If GetTempFileName("c:\temp", "xyz", 0, buffer) = 0 Then
        Throw New System.ComponentModel.Win32Exception()
    End If
    Dim filename = buffer.ToString()

pinvoke.net网站往往是pinvoke声明的一个不错的资源。不过这个版本,VB.NET版本非常混乱。