From fc5ca5e39e6c5af3471a8f142c32b047b257fe1e Mon Sep 17 00:00:00 2001 From: guanren Date: Fri, 18 Oct 2024 13:23:04 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8D=95=E7=8B=AC=E5=89=A5=E7=A6=BB=E5=87=BA?= =?UTF-8?q?=E6=9D=A5=E4=B8=80=E4=B8=AA=E4=B8=BAwindows=E7=9A=84,=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0RandNumLen=E4=B8=BA=E5=8F=96=E6=8C=87=E5=AE=9A?= =?UTF-8?q?=E9=95=BF=E5=BA=A6=E9=9A=8F=E6=9C=BA=E6=95=B0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/api/packages/random.md | 26 +++++++++++ fileutil/file.go | 34 ++------------- fileutil/file_test.go | 7 --- fileutil/file_windows.go | 81 +++++++++++++++++++++++++++++++++++ fileutil/file_windows_test.go | 13 ++++++ random/random.go | 8 ++++ 6 files changed, 131 insertions(+), 38 deletions(-) create mode 100644 fileutil/file_windows.go create mode 100644 fileutil/file_windows_test.go diff --git a/docs/api/packages/random.md b/docs/api/packages/random.md index 895f1ba..9c17959 100644 --- a/docs/api/packages/random.md +++ b/docs/api/packages/random.md @@ -40,6 +40,7 @@ import ( - [RandStringSlice](#RandStringSlice) - [RandBool](#RandBool) - [RandBoolSlice](#RandBoolSlice) +- [RandNumLen](#RandNumLen)
@@ -522,4 +523,29 @@ func main() { result := random.RandBoolSlice(2) fmt.Println(result) // [true false] (random) } +``` +### RandNumLen + +

生成指定长度的随机数

+ +函数签名: + +```go +func RandNumLen(len int) int +``` + +实例:[运行](https://go.dev/play/p/o-VSjPjnILI) + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/v2/random" +) + +func main() { + i := random.RandNumLen(2) + fmt.Println(i) +} ``` \ No newline at end of file diff --git a/fileutil/file.go b/fileutil/file.go index 5cd2748..7921f46 100644 --- a/fileutil/file.go +++ b/fileutil/file.go @@ -1,3 +1,6 @@ +//go:build windows +// +build windows + // Copyright 2021 dudaodong@gmail.com. All rights reserved. // Use of this source code is governed by MIT license. @@ -15,7 +18,6 @@ import ( "errors" "fmt" "github.com/duke-git/lancet/v2/validator" - "golang.org/x/sys/windows" "io" "io/fs" "net/http" @@ -25,7 +27,6 @@ import ( "sort" "strings" "sync" - "unsafe" ) // FileReader is a reader supporting offset seeking and reading one @@ -948,32 +949,3 @@ 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 - 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 b10f42c..77259ea 100644 --- a/fileutil/file_test.go +++ b/fileutil/file_test.go @@ -619,10 +619,3 @@ 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/fileutil/file_windows.go b/fileutil/file_windows.go new file mode 100644 index 0000000..fd41b1a --- /dev/null +++ b/fileutil/file_windows.go @@ -0,0 +1,81 @@ +//go:build windows + +package fileutil + +import ( + "fmt" + "syscall" + "unsafe" +) + +// tagVS_FIXEDFILEINFO 参考结构体https://learn.microsoft.com/zh-cn/windows/win32/api/verrsrc/ns-verrsrc-vs_fixedfileinfo +type tagVS_FIXEDFILEINFO struct { + Signature uint32 + StructVersion uint32 + FileVersionMS uint32 + FileVersionLS uint32 + ProductVersionMS uint32 + ProductVersionLS uint32 + FileFlagsMask uint32 + FileFlags uint32 + FileOS uint32 + FileType uint32 + FileSubtype uint32 + FileDateMS uint32 + FileDateLS uint32 +} + +// GetExeDllVersion 获取exe或dll文件的版本信息 +func GetExeDllVersion(filePath string) (string, error) { + // 加载系统dll + versionDLL := syscall.NewLazyDLL("version.dll") + getFileVersionInfoSize := versionDLL.NewProc("GetFileVersionInfoSizeW") + getFileVersionInfo := versionDLL.NewProc("GetFileVersionInfoW") + verQueryValue := versionDLL.NewProc("VerQueryValueW") + + // 转换路径为UTF-16 + filePathPtr, err := syscall.UTF16PtrFromString(filePath) + if err != nil { + return "", fmt.Errorf("unable to convert file path to UTF-16: %w", err) + } + + // 获取version信息大小 + size, _, err := getFileVersionInfoSize.Call( + uintptr(unsafe.Pointer(filePathPtr)), + 0, + ) + if size == 0 { + return "", fmt.Errorf("unable to obtain version information size: %v", err) + } + + // 加载version信息 + data := make([]byte, size) + ret, _, err := getFileVersionInfo.Call(uintptr(unsafe.Pointer(filePathPtr)), 0, size, uintptr(unsafe.Pointer(&data[0]))) + if ret == 0 { + return "", fmt.Errorf("unable to obtain version information: %v", err) + } + + // 查询version信息 + var fixedInfo *tagVS_FIXEDFILEINFO + var fixedInfoLen uint32 + u16, err := syscall.UTF16PtrFromString(`\`) + if err != nil { + return "", fmt.Errorf("unable to convert file path to UTF-16: %w", err) + } + ret, _, err = verQueryValue.Call( + uintptr(unsafe.Pointer(&data[0])), + uintptr(unsafe.Pointer(u16)), + uintptr(unsafe.Pointer(&fixedInfo)), + uintptr(unsafe.Pointer(&fixedInfoLen)), + ) + if ret == 0 { + return "", fmt.Errorf("unable to query version information: %v", err) + } + + // 转换结构体 + major := fixedInfo.FileVersionMS >> 16 + minor := fixedInfo.FileVersionMS & 0xFFFF + build := fixedInfo.FileVersionLS >> 16 + revision := fixedInfo.FileVersionLS & 0xFFFF + return fmt.Sprintf("%d.%d.%d.%d", major, minor, build, revision), nil +} diff --git a/fileutil/file_windows_test.go b/fileutil/file_windows_test.go new file mode 100644 index 0000000..d6f7ac4 --- /dev/null +++ b/fileutil/file_windows_test.go @@ -0,0 +1,13 @@ +//go:build windows + +package fileutil + +import "testing" + +func TestGetExeDllVersion(t *testing.T) { + v, err := GetExeDllVersion(`C:\Windows\System32\cmd.exe`) + if err != nil { + t.Error(err) + } + t.Log(v) +} diff --git a/random/random.go b/random/random.go index 5192382..bceca50 100644 --- a/random/random.go +++ b/random/random.go @@ -327,3 +327,11 @@ func UUIdV4() (string, error) { return fmt.Sprintf("%x-%x-%x-%x-%x", uuid[0:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[10:]), nil } + +// RandNumLen 生成一个长度为len的随机数 +func RandNumLen(len int) int { + m := int(math.Pow10(len) - 1) + i := int(math.Pow10(len - 1)) + ret := rand.Intn(m-i+1) + i + return ret +}