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

Go调用GetFileInformationByHandle时出现"The handle is invalid"错误排查

问题分析与修复方案

哦,我一眼就看到问题所在了——你完全误用了GetFileVersionInfoSize返回的那个所谓的"handle",它根本不是你需要的文件句柄!

错误原因详解

windows.GetFileVersionInfoSize的第二个参数&handle,这个参数的作用不是返回文件句柄,而是用来接收一个与版本信息资源相关的临时值(多数情况下,成功调用后这个值也只是给后续GetFileVersionInfo函数使用,和文件本身的句柄没有任何关系)。你初始化的handle变量默认是0,直接把这个无效值传给GetFileInformationByHandle,必然会触发"无效句柄"的错误。

修复方案

方案1:直接用windows.Open获取合法文件句柄

这是最直接的方式,通过Windows API打开文件并获取句柄,专门用于后续的文件信息查询:

package main

import (
    "log"

    "golang.org/x/sys/windows"
)

func main() {
    name := `C:\Windows\System32\cmd.exe`

    // 以只读模式打开文件,设置合理的共享权限
    handle, err := windows.Open(
        name,
        windows.GENERIC_READ,
        windows.FILE_SHARE_READ|windows.FILE_SHARE_WRITE|windows.FILE_SHARE_DELETE,
    )
    if err != nil {
        log.Fatalf("Failed to open file: %s", err.Error())
    }
    defer windows.CloseHandle(handle) // 务必记得关闭句柄,避免资源泄漏

    var hndlFileInfo windows.ByHandleFileInformation
    err = windows.GetFileInformationByHandle(handle, &hndlFileInfo)
    if err != nil {
        if err == windows.ERROR_INVALID_HANDLE {
            log.Println("Error is invalid handle error.")
        }
        log.Fatalf("GetFileInformationByHandle error: path: %s %s", name, err.Error())
    }

    // 将Windows文件时间转换为Go标准时间格式
    creationTime := windows.FiletimeToTime(hndlFileInfo.CreationTime)
    log.Printf("File creation time: %v", creationTime)
    log.Println("Success!")
}

方案2:从已打开的os.File中获取底层句柄

如果你已经通过os包打开了文件,可以直接提取它的底层句柄来使用:

package main

import (
    "log"
    "os"
    "syscall"

    "golang.org/x/sys/windows"
)

func main() {
    name := `C:\Windows\System32\cmd.exe`

    file, err := os.Open(name)
    if err != nil {
        log.Fatalf("Unable to open %s: %s", name, err.Error())
    }
    defer file.Close()

    // 从os.File中提取底层的syscall句柄,转换为windows.Handle
    sysHandle := syscall.Handle(file.Fd())
    handle := windows.Handle(sysHandle)

    var hndlFileInfo windows.ByHandleFileInformation
    err = windows.GetFileInformationByHandle(handle, &hndlFileInfo)
    if err != nil {
        if err == windows.ERROR_INVALID_HANDLE {
            log.Println("Error is invalid handle error.")
        }
        log.Fatalf("GetFileInformationByHandle error: path: %s %s", name, err.Error())
    }

    creationTime := windows.FiletimeToTime(hndlFileInfo.CreationTime)
    log.Printf("File creation time: %v", creationTime)
    log.Println("Success!")
}

额外注意事项

  • 无论哪种方案,都要记得关闭文件句柄(用defer语句确保退出前执行),防止系统资源泄漏。
  • GetFileVersionInfoSize的那个参数不要用来做文件句柄,它的唯一用途是配合GetFileVersionInfo获取文件版本信息,和文件本身的操作无关。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 17:40:17