You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 4.7.2下VB.NET超长路径文件移动失败问题求助

解决方案

核心问题:MoveFileW的路径格式要求

MoveFileW 对长路径的处理要求源路径和目标路径必须统一使用 \\?\ 前缀,不能混合带前缀和无前缀的路径,也不能随意移除目标路径的前缀——你之前移除目标路径前缀的操作是错误的,这会导致系统无法识别长路径。

修正步骤与代码

  1. 编写路径转换辅助函数:将普通Windows路径转为\\?\格式,确保Win32 API能识别长路径
  2. 统一源/目标路径格式:临时文件夹路径虽短,但统一格式可避免兼容性问题
  3. 保留目标路径的前缀,同时添加错误排查逻辑定位问题
Imports System.Runtime.InteropServices

' 声明MoveFileW API
<DllImport("kernel32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Private Shared Function MoveFileW(lpExistingFileName As String, lpNewFileName As String) As Boolean
End Function

' 辅助函数:将普通路径转换为\\?\格式的长路径
Private Function GetLongPath(path As String) As String
    ' 已带前缀则直接返回
    If path.StartsWith("\\?\") Then
        Return path
    End If
    ' 先转绝对路径避免相对路径问题
    Dim absolutePath = IO.Path.GetFullPath(path)
    ' 添加长路径前缀
    Return $"\\?\{absolutePath}"
End Function

' 修正后的文件移动逻辑
Sub MoveFileToLongPath(filename As String)
    ' 构建源文件路径(临时文件夹)
    Dim sourcePath = My.Computer.FileSystem.CombinePath(My.Computer.FileSystem.SpecialDirectories.Temp, $"{filename}.ddb")
    Dim longSourcePath = GetLongPath(sourcePath)

    ' 构建目标文件路径(你的长路径)
    Dim baseLongPath = "\\?\C:\Basedir\Long-path-base"
    Dim destinationPath = My.Computer.FileSystem.CombinePath(baseLongPath, $"{filename}.ddb")
    Dim longDestinationPath = GetLongPath(destinationPath)

    ' 执行移动
    Dim success As Boolean = MoveFileW(longSourcePath, longDestinationPath)
    If Not success Then
        ' 获取Win32错误码排查问题
        Dim errorCode = Marshal.GetLastWin32Error()
        Throw New System.ComponentModel.Win32Exception(errorCode)
    End If
End Sub

额外优化:启用.NET 4.7.2原生长路径支持

.NET 4.7.2已原生支持长路径,无需依赖Win32 API,只需在app.config中添加配置:

<configuration>
  <runtime>
    <AppContextSwitchOverrides value="Switch.System.IO.UseLegacyPathHandling=false;Switch.System.IO.BlockLongPaths=false" />
  </runtime>
</configuration>

配置后直接使用System.IO.File.Move即可处理长路径,无需手动添加前缀:

Dim sourcePath = My.Computer.FileSystem.CombinePath(My.Computer.FileSystem.SpecialDirectories.Temp, $"{filename}.ddb")
Dim destinationPath = My.Computer.FileSystem.CombinePath("C:\Basedir\Long-path-base", $"{filename}.ddb")
System.IO.File.Move(sourcePath, destinationPath)

常见排查点

如果移动仍失败,通过Marshal.GetLastWin32Error()获取错误码定位:

  • 错误码3:路径不存在(检查目标文件夹是否真的创建成功)
  • 错误码5:权限不足(确保程序有目标文件夹的写入权限)
  • 错误码87:参数错误(路径格式错误,检查前缀是否正确添加)

内容的提问来源于stack exchange,提问作者Tobbe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 19:42:38