mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-04 12:52:28 +08:00
feat:add GetExeDllVersion for fileutil,random,package (#257)
* 增加GetExeDllVersion函数获取exe,dll版本号 * 多打文字 * 定位忘记... * 单独剥离出来一个为windows的,增加RandNumLen为取指定长度随机数. * .... * 增加test测试
This commit is contained in:
@@ -52,7 +52,7 @@ import (
|
||||
- [ReadFile](#ReadFile)
|
||||
- [ChunkRead](#ChunkRead)
|
||||
- [ParallelChunkRead](#ParallelChunkRead)
|
||||
|
||||
- [GetVersion](#Version)
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 文档
|
||||
@@ -1077,3 +1077,33 @@ func main() {
|
||||
// 2
|
||||
}
|
||||
```
|
||||
### <span id="Version">GetExeDllVersion</span>
|
||||
|
||||
<p>返回exe,dll文件版本号(仅Window平台).</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func GetExeDllVersion(filePath string) (string, error)
|
||||
```
|
||||
|
||||
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/s_Tl7lZoAaY)</span></b>
|
||||
|
||||
```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
|
||||
}
|
||||
```
|
||||
@@ -40,6 +40,7 @@ import (
|
||||
- [RandStringSlice](#RandStringSlice)
|
||||
- [RandBool](#RandBool)
|
||||
- [RandBoolSlice](#RandBoolSlice)
|
||||
- [RandNumLen](#RandNumLen)
|
||||
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
@@ -523,3 +524,28 @@ func main() {
|
||||
fmt.Println(result) // [true false] (random)
|
||||
}
|
||||
```
|
||||
### <span id="RandNumLen">RandNumLen</span>
|
||||
|
||||
<p>生成指定长度的随机数</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func RandNumLen(len int) int
|
||||
```
|
||||
|
||||
<b>实例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/o-VSjPjnILI)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/random"
|
||||
)
|
||||
|
||||
func main() {
|
||||
i := random.RandNumLen(2)
|
||||
fmt.Println(i)
|
||||
}
|
||||
```
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"encoding/csv"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
"io"
|
||||
"io/fs"
|
||||
"net/http"
|
||||
@@ -23,8 +24,6 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/duke-git/lancet/v2/validator"
|
||||
)
|
||||
|
||||
// FileReader is a reader supporting offset seeking and reading one
|
||||
|
||||
81
fileutil/file_windows.go
Normal file
81
fileutil/file_windows.go
Normal file
@@ -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
|
||||
}
|
||||
13
fileutil/file_windows_test.go
Normal file
13
fileutil/file_windows_test.go
Normal file
@@ -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)
|
||||
}
|
||||
1
go.mod
1
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
|
||||
)
|
||||
|
||||
4
go.sum
4
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=
|
||||
|
||||
@@ -327,3 +327,12 @@ 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的随机数
|
||||
// Play: https://go.dev/play/p/jpIalcD5rMo
|
||||
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
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package random
|
||||
import (
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
@@ -361,3 +362,9 @@ func TestRandBoolSlice(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
func TestRandNumLen(t *testing.T) {
|
||||
t.Parallel()
|
||||
randi := RandNumLen(6)
|
||||
assert := internal.NewAssert(t, "TestRandNumLen")
|
||||
assert.Equal(6, len(strconv.Itoa(randi)))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user