卓越飞翔博客卓越飞翔博客

卓越飞翔 - 您值得收藏的技术分享站
技术文章34680本站已运行393

使用使用 GetFileVersionInfoSize 初始化的句柄调用 GetFileInformationByHandle 时出现“句柄无效”错误

使用使用 getfileversioninfosize 初始化的句柄调用 getfileinformationbyhandle 时出现“句柄无效”错误

php小编鱼仔在使用GetFileVersionInfoSize初始化的句柄调用GetFileInformationByHandle时遇到了"句柄无效"错误。这个错误通常是由于句柄无法正确地识别文件信息导致的。解决这个问题的方法有多种,例如检查句柄是否正确初始化,确认文件路径是否正确,以及检查文件是否已被其他进程占用。通过仔细排查和处理,可以解决这个问题并顺利获取文件信息。

问题内容

我正在尝试在 windows 上使用 go 以编程方式获取文件信息,包括文件的创建时间。

我在 golang.org/x/sys/windows 中发现一个函数,它返回有关何时创建文件的信息,该函数是 getfileinformationbyhandle (go 文档、windows api 文档)。但是,我使用此函数编写的代码给了我一个 the handle is invalid 错误。

这是我的代码:

package main

import (
    "log"
    "os"

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

func main() {
    name := `c:windowssystem32cmd.exe`

    fileinfo, err := os.stat(name)
    if err != nil {
        log.fatalf("unable to stat %s: %s", name, err.error())
    }

    log.printf("%s has base name %s.n", name, fileinfo.name())

    var handle windows.handle
    _, err = windows.getfileversioninfosize(name, &handle)
    if err != nil && err != windows.error_file_not_found && err != windows.error_resource_type_not_found {
        log.fatalf("getfileversioninfosize error: path: %s %s", name, err.error())
    }

    var hndlfileinfo windows.byhandlefileinformation
    err = windows.getfileinformationbyhandle(handle, &hndlfileinfo)
    if err != nil {
        if err == windows.error_invalid_handle { // https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499-
            log.println("error is invalid handle error.")
        }
        log.fatalf("getfileinformationbyhandle error: path: %s %s", name, err.error())
    }

    log.println("success!")
}

当我运行它时,我得到以下输出:

2023/01/11 14:43:19 c:windowssystem32cmd.exe has base name cmd.exe.
2023/01/11 14:43:19 error is invalid handle error.
2023/01/11 14:43:19 getfileinformationbyhandle error: path: c:windowssystem32cmd.exe the handle is invalid.

我已确认文件路径有效(加上 os.stat 调用不会返回错误):

我知道 system32 目录对于 32 位 windows 程序不可见,但我已经使用 git-bash 上的 file 工具验证了我的可执行文件是 64 位程序:

$ file win_handle_test.exe
win_handle_test.exe: PE32+ executable (console) x86-64 (stripped to external PDB), for MS Windows

既然路径应该是有效的,我可能做错了什么,导致我得到无效的句柄?

解决方法

根据这个答案,我找到了另一种获取创建时间的方法:

package main

import (
    "log"
    "os"
    "time"
    "syscall"
)

func main() {
    name := `c:windowssystem32cmd.exe`

    fileinfo, err := os.stat(name)
    if err != nil {
        log.fatalf("unable to stat %s: %s", name, err.error())
    }

    log.printf("%s has base name %s.n", name, fileinfo.name())

    data := fileinfo.sys().(*syscall.win32fileattributedata)
    ctime := time.unix(0, data.creationtime.nanoseconds())

    log.printf("ctime in utc           : %vn", ctime.utc())
    log.printf("ctime in local timezone: %vn", ctime)
}

输出:

2023/01/11 15:03:58 C:WindowsSystem32cmd.exe has base name cmd.exe.
2023/01/11 15:03:58 cTime in UTC           : 2022-05-10 17:34:57.9429156 +0000 UTC
2023/01/11 15:03:58 cTime in local timezone: 2022-05-10 13:34:57.9429156 -0400 EDT

此输出与文件属性视图中的创建时间匹配。

尽管 filetime本身的时间自 1601 年 1 月 1 日 utc 起,time.unixnanoseconds 函数 基于自 1970 年 1 月 1 日 utc 以来的时间。

上一篇: Rust 相当于 Go 中的append 是什么?
下一篇: 返回列表
留言与评论(共有 0 条评论)
   
验证码:
隐藏边栏