diff --git a/docs/api/packages/fileutil.md b/docs/api/packages/fileutil.md index 129bbe0..7a28045 100644 --- a/docs/api/packages/fileutil.md +++ b/docs/api/packages/fileutil.md @@ -1076,4 +1076,34 @@ func main() { // Jim,21,male // 2 } +``` +### GetExeDllVersion + +

返回exe,dll文件版本号(仅Window平台).

+ +函数签名: + +```go +func GetExeDllVersion(filePath string) (string, error) +``` + +示例:[运行](https://go.dev/play/p/s_Tl7lZoAaY) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/fileutil" +) + +func main() { + v, err := fileutil.GetExeDllVersion(`C:\Program Files\Tencent\WeChat\WeChat.exe`) + if err != nil { + panic(err) + } + fmt.Println(v) + // Output: + // 3.9.10.19 +} ``` \ No newline at end of file diff --git a/fileutil/file.go b/fileutil/file.go index 585b080..67d5d30 100644 --- a/fileutil/file.go +++ b/fileutil/file.go @@ -14,8 +14,11 @@ import ( "encoding/csv" "errors" "fmt" + "github.com/duke-git/lancet/v2/validator" + "golang.org/x/sys/windows" "io" "io/fs" + "log" "net/http" "os" "path/filepath" @@ -23,8 +26,7 @@ import ( "sort" "strings" "sync" - - "github.com/duke-git/lancet/v2/validator" + "unsafe" ) // FileReader is a reader supporting offset seeking and reading one @@ -947,3 +949,33 @@ func ParallelChunkRead(filePath string, linesCh chan<- []string, chunkSizeMB, ma return nil } + +// GetExeDllVersion 获取exe或dll文件的版本信息 +func GetExeDllVersion(filePath string) (string, error) { + // 获取版本信息大小 + size, err := windows.GetFileVersionInfoSize(filePath, nil) + if err != nil { + return "", fmt.Errorf("无法获取版本信息大小: %w", err) + } + // 读取版本信息 + data := make([]byte, size) + err = windows.GetFileVersionInfo(filePath, 0, size, unsafe.Pointer(&data[0])) + if err != nil { + return "", fmt.Errorf("无法获取版本信息: %w", err) + } + // 查询版本信息 + var fixedInfo *windows.VS_FIXEDFILEINFO + var fixedInfoLen uint32 + err = windows.VerQueryValue(unsafe.Pointer(&data[0]), `\`, unsafe.Pointer(&fixedInfo), &fixedInfoLen) + if err != nil { + return "", fmt.Errorf("无法查询版本信息: %w", err) + } + + // 提取版本号 + major := fixedInfo.FileVersionMS >> 16 + minor := fixedInfo.FileVersionMS & 0xFFFF + build := fixedInfo.FileVersionLS >> 16 + revision := fixedInfo.FileVersionLS & 0xFFFF + log.Println(fixedInfo.FileVersionMS) + return fmt.Sprintf("%d.%d.%d.%d", major, minor, build, revision), nil +} diff --git a/fileutil/file_test.go b/fileutil/file_test.go index 77259ea..b10f42c 100644 --- a/fileutil/file_test.go +++ b/fileutil/file_test.go @@ -619,3 +619,10 @@ func TestChunkRead(t *testing.T) { assert.Equal("Jim,21,male", lines[1]) } +func TestGetExeDllVersion(t *testing.T) { + v, err := GetExeDllVersion(`C:\Program Files\Tencent\WeChat\WeChat.exe`) + if err != nil { + t.Error(err) + } + t.Log(v) +} diff --git a/go.mod b/go.mod index e5be56c..cca26aa 100644 --- a/go.mod +++ b/go.mod @@ -4,5 +4,6 @@ go 1.18 require ( golang.org/x/exp v0.0.0-20221208152030-732eee02a75a + golang.org/x/sys v0.5.0 golang.org/x/text v0.9.0 ) diff --git a/go.sum b/go.sum index 931837d..f1ac8c7 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,6 @@ golang.org/x/exp v0.0.0-20221208152030-732eee02a75a h1:4iLhBPcpqFmylhnkbY3W0ONLUYYkDAW9xMFLfxgsvCw= golang.org/x/exp v0.0.0-20221208152030-732eee02a75a/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= -golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=