php小編魚仔在使用GetFileVersionInfoSize初始化的句柄調(diào)用GetFileInformationByHandle時遇到了”句柄無效”錯誤。這個錯誤通常是由于句柄無法正確地識別文件信息導(dǎo)致的。解決這個問題的方法有多種,例如檢查句柄是否正確初始化,確認(rèn)文件路徑是否正確,以及檢查文件是否已被其他進程占用。通過仔細排查和處理,可以解決這個問題并順利獲取文件信息。
問題內(nèi)容
我正在嘗試在 windows 上使用 go 以編程方式獲取文件信息,包括文件的創(chuàng)建時間。
我在 golang.org/x/sys/windows 中發(fā)現(xiàn)一個函數(shù),它返回有關(guān)何時創(chuàng)建文件的信息,該函數(shù)是 getfileinformationbyhandle (go 文檔、windows api 文檔)。但是,我使用此函數(shù)編寫的代碼給了我一個 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!")
}
登錄后復(fù)制
當(dāng)我運行它時,我得到以下輸出:
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.
登錄后復(fù)制
我已確認(rèn)文件路徑有效(加上 os.stat 調(diào)用不會返回錯誤):
我知道 system32 目錄對于 32 位 windows 程序不可見,但我已經(jīng)使用 git-bash 上的 file 工具驗證了我的可執(zhí)行文件是 64 位程序:
$ file win_handle_test.exe win_handle_test.exe: PE32+ executable (console) x86-64 (stripped to external PDB), for MS Windows
登錄后復(fù)制
既然路徑應(yīng)該是有效的,我可能做錯了什么,導(dǎo)致我得到無效的句柄?
解決方法
根據(jù)這個答案,我找到了另一種獲取創(chuàng)建時間的方法:
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)
}
登錄后復(fù)制
輸出:
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
登錄后復(fù)制
此輸出與文件屬性視圖中的創(chuàng)建時間匹配。
盡管 filetime本身的時間自 1601 年 1 月 1 日 utc 起,time.unix 和 nanoseconds 函數(shù) 基于自 1970 年 1 月 1 日 utc 以來的時間。






