首頁  >  文章  >  後端開發  >  使用使用 GetFileVersionInfoSize 初始化的句柄呼叫 GetFileInformationByHandle 時出現「句柄無效」錯誤

使用使用 GetFileVersionInfoSize 初始化的句柄呼叫 GetFileInformationByHandle 時出現「句柄無效」錯誤

WBOY
WBOY轉載
2024-02-09 10:24:201057瀏覽

使用使用 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:\windows\system32\cmd.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:\windows\system32\cmd.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:\windows\system32\cmd.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:\windows\system32\cmd.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           : %v\n", ctime.utc())
    log.printf("ctime in local timezone: %v\n", ctime)
}

輸出:

2023/01/11 15:03:58 C:\Windows\System32\cmd.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 以來的時間。

以上是使用使用 GetFileVersionInfoSize 初始化的句柄呼叫 GetFileInformationByHandle 時出現「句柄無效」錯誤的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除