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

使用SHFileOperation()的FO_COPY复制单个字体文件至C:\Windows\Fonts失败求助

关于SHFileOperation() FO_COPY复制字体到Fonts文件夹的问题

我尝试用SHFileOperation()的FO_COPY方法将单个字体文件复制到C:\Windows\Fonts文件夹(已知其他文件复制方法,仅针对此API排查问题)。以下是相关代码及遇到的问题:

声明部分

Private Structure SHFILEOPSTRUCT

    Dim hwnd As Integer
    Dim wFunc As Integer
    Dim pFrom As String
    Dim pTo As String
    Dim fFlags As Short
    Dim fAnyOperationsAborted As Boolean
    Dim hNameMappings As Integer
    Dim lpszProgressTitle As String

End Structure

<DllImport("shell32.dll", EntryPoint:="SHFileOperation", CharSet:=CharSet.Auto, SetLastError:=True, ThrowOnUnmappableChar:=True)>
Private Function SHFileOperation(ByRef lpFileOp As SHFILEOPSTRUCT) As Integer
End Function

Private Const FO_COPY As Integer = &H2S
Private Const FOF_NOCONFIRMATION As Integer = &H10S
Private Const FOF_SILENT As Integer = &H4S

函数部分

Dim shf As SHFILEOPSTRUCT
Dim strWinFontFolder As String = Environment.ExpandEnvironmentVariables("%WINDIR%" & "\Fonts")

With shf
    .wFunc = FO_COPY
    .pFrom = String.Format("{0}{1}{1}", strFontPath, vbNullChar)
    .pTo = String.Format("{0}{1}{1}", strWinFontFolder, vbNullChar)
    .fFlags = FOF_NOCONFIRMATION Or FOF_SILENT
    .lpszProgressTitle = String.Format("Sending {0} to the Font Folder", strFontPath)
End With

Try
    SHFileOperation(shf)
Catch ex As Exception
    Debug.WriteLine(String.Format("SHFILEOPSTRUCT: {0}", ex.Message))
End Try

微软文档说明

重要提示:必须确保源路径和目标路径以双空字符结尾。普通字符串仅以单个空字符结尾,如果在源或目标参数中传递这样的值,函数无法识别字符串的结束位置,会继续在内存中读取直到遇到随机的双空字符。这至少会导致缓冲区溢出,甚至可能意外删除无关数据。

遇到的问题

  • 按文档要求为.pTo和.pFrom添加双空字符结尾时,无任何反应,文件未复制,也无错误提示。
  • 仅添加单个空字符结尾时,出现错误(英文系统却显示亚洲字符)。
    注:调用该函数前已通过If File.Exists(strFontPath) = True Then确认文件存在。

请问无法复制的原因是什么?


排查与解决方向

  1. 权限缺失:Fonts是系统受保护目录,普通权限下无法直接写入。需以管理员身份运行程序,否则SHFileOperation会静默失败,不会抛出异常。
  2. 字符串处理问题:
    • 用String.Format拼接双空字符可能存在隐式处理问题,直接改用strFontPath & vbNullChar & vbNullChar和strWinFontFolder & vbNullChar & vbNullChar来生成路径,避免格式解析干扰。
    • 目标路径C:\Windows\Fonts无需加末尾反斜杠,尝试去掉反斜杠后再加双空字符。
  3. Flags参数干扰:FOF_SILENT会隐藏所有系统提示,包括权限不足的警告。先移除该参数,查看是否有弹窗提示,快速定位问题。
  4. 未检查返回值:SHFileOperation的返回值直接反映操作结果,0表示成功,非0则为错误码。修改代码捕获返回值并获取详细错误:
Imports System.Runtime.InteropServices

' ... 原有代码 ...

Try
    Dim result As Integer = SHFileOperation(shf)
    If result <> 0 Then
        Dim errorCode As Integer = Marshal.GetLastWin32Error()
        Debug.WriteLine($"操作失败,错误码:{errorCode}")
    End If
Catch ex As Exception
    Debug.WriteLine($"异常信息:{ex.Message}")
End Try

内容的提问来源于stack exchange,提问作者J. Scott Elblein

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 13:31:00