GetTempFileName 抛出 'System.AccessViolationException' vb.net

GetTempFileName throwing 'System.AccessViolationException' vb.net

我是 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(),但我可能需要执行多次操作才能获得以特定单词为前缀并位于特定位置的文件名。 我交叉检查了这些值,它们不是坏数据。 我尝试了多种解决方案,但其中 none 有效。 有人可以帮忙吗?提前致谢!

当您将 Pinvoke 声明移动到 VB.NET 时,需要重写它们。许多差异,例如 Long 需要是 Integer,如果 winapi 函数 returns 是一个字符串,那么您需要使用 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 版本相当笨拙。