【问题标题】:GetTempFileName throwing 'System.AccessViolationException' vb.netGetTempFileName 抛出 'System.AccessViolationException' vb.net
【发布时间】:2015-03-27 16:13:11
【问题描述】:

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

【问题讨论】:

  • 在 NET 中使用 System.IO.Path.GetTempFileName() 并摆脱 PInvoke
  • 由于我的要求是:需要创建一个具有特定前缀的临时文件并在特定位置创建,我必须操作 GetTempFileName(),还是我们有相同的方法?

标签: vb.net kernel32


【解决方案1】:

将 Pinvoke 声明移至 VB.NET 时需要重写它们。许多差异,例如 Long 需要是 Integer,如果 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 版本相当笨拙。

【讨论】:

  • 完美!问题是使用 Long。当更改为整数时,它就像一个魅力!谢谢汉斯帕桑特!
  • 嗯,不,使用字符串作为第四个参数是最严重的问题。您只是还没有机会破坏 GC 堆。 AVE是一个很好的问题,你知道你做错了。堆损坏是无声的杀手。不要跳过该更改。
  • 添加了字符串生成器!感谢汉斯的建议!
猜你喜欢
  • 2020-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多