diff --git a/dotnet/README.md b/dotnet/README.md new file mode 100644 index 0000000..02ea4ab --- /dev/null +++ b/dotnet/README.md @@ -0,0 +1,29 @@ +# dotnet + +读取本机 .NET Framework 安装信息(Windows 注册表):v2/v3/v3.5/v4 各版本 +安装状态与版本号,以及 4.5+ 的 release key 换算。 + +> 迁移自 go-hua/netFramework 并更名:原包名 `netFramework` 极易误读为 +> "网络框架",实为 .NET Framework 信息查询,故更名 `dotnet`。 +> **仅 Windows 可用**(读注册表)。 + +## 用法 + +```go +import "git.zeroonesoft.cn/golib/zogo/dotnet" + +v2, err := dotnet.GetV2Info() // {Install, Version, ServicePack} +v3, err := dotnet.GetV3Info() +v35, err := dotnet.GetV35Info() +v4, err := dotnet.GetV4Info() // {Install, Release, Version} + +// release key → "4.8" 之类的展示版本 +name := dotnet.CheckFor45PlusVersion(releaseKey) +``` + +完整可运行例程:[examples/dotnet/main.go](../examples/dotnet/main.go) + +## 注意 + +- 非 Windows 平台调用返回错误(构建不隔离,运行时区分)。 +- .NET 5+ 不再写 .NET Framework 的注册表键,本包只覆盖 Framework 系。 diff --git a/dotnet/dotnet.go b/dotnet/dotnet.go new file mode 100644 index 0000000..cb234a7 --- /dev/null +++ b/dotnet/dotnet.go @@ -0,0 +1,180 @@ +// Package dotnet 读取本机 .NET Framework 安装信息(Windows 注册表)。 +package dotnet + +import "golang.org/x/sys/windows/registry" + +const ( + V45MinValue = 378389 + V451MinValue = 378675 + V452MinValue = 379893 + V46MinValue = 393295 + V461MinValue = 394254 + V462MinValue = 394802 + V47MinValue = 460798 + V471MinValue = 461308 + V472MinValue = 461808 + V48MinValue = 528040 + V481MinValue = 533320 +) + +// V2Info .NET Framework 2.0 安装信息 +type V2Info struct { + Install uint64 + Version string +} + +// V3Info .NET Framework 3.0 安装信息 +type V3Info struct { + Install uint64 + Version string +} + +// V35Info .NET Framework 3.5 安装信息 +type V35Info struct { + Install uint64 + InstallPath string + Version string +} + +// V4Info .NET Framework 4.x 安装信息 +type V4Info struct { + Install uint64 + InstallPath string + Release uint64 + Version string +} + +// GetV2Info 获取 .NET Framework 2.0 安装信息 +func GetV2Info() (V2Info, error) { + key, err := registry.OpenKey(registry.LOCAL_MACHINE, "SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v2.0.50727", registry.READ) + info := V2Info{} + if err != nil { + return info, err + } + install, _, err := key.GetIntegerValue("Install") + if err != nil { + return info, err + } + version, _, err := key.GetStringValue("Version") + if err != nil { + return info, err + } + info.Install = install + info.Version = version + return info, nil +} + +// GetV3Info 获取 .NET Framework 3.0 安装信息 +func GetV3Info() (V3Info, error) { + key, err := registry.OpenKey(registry.LOCAL_MACHINE, "SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v3.0\\Setup", registry.READ) + info := V3Info{} + if err != nil { + return info, err + } + install, _, err := key.GetIntegerValue("InstallSuccess") + if err != nil { + return info, err + } + version, _, err := key.GetStringValue("Version") + if err != nil { + return info, err + } + info.Install = install + info.Version = version + return info, nil +} + +// GetV35Info 获取 .NET Framework 3.5 安装信息 +func GetV35Info() (V35Info, error) { + key, err := registry.OpenKey(registry.LOCAL_MACHINE, "SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v3.5", registry.READ) + info := V35Info{} + if err != nil { + return info, err + } + install, _, err := key.GetIntegerValue("Install") + if err != nil { + return info, err + } + installPath, _, err := key.GetStringValue("InstallPath") + if err != nil { + return info, err + } + version, _, err := key.GetStringValue("Version") + if err != nil { + return info, err + } + info.Install = install + info.InstallPath = installPath + info.Version = version + return info, nil +} + +// GetV4Info 获取 .NET Framework 4.x 安装信息 +func GetV4Info() (V4Info, error) { + key, err := registry.OpenKey(registry.LOCAL_MACHINE, "SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full", registry.READ) + info := V4Info{} + if err != nil { + return info, err + } + install, _, err := key.GetIntegerValue("Install") + if err != nil { + return info, err + } + installPath, _, err := key.GetStringValue("InstallPath") + if err != nil { + return info, err + } + release, _, err := key.GetIntegerValue("Release") + if err != nil { + return info, err + } + version, _, err := key.GetStringValue("Version") + if err != nil { + return info, err + } + info.Install = install + info.InstallPath = installPath + info.Release = release + info.Version = version + return info, nil +} + +// CheckFor45PlusVersion 根据 Release 注册表值判断 .NET Framework 4.5+ 的具体版本 +func CheckFor45PlusVersion(releaseKey int) string { + if releaseKey >= 533320 { + return "4.8.1 or later" + } + if releaseKey >= 528040 { + return "4.8" + } + if releaseKey >= 461808 { + return "4.7.2" + } + if releaseKey >= 461308 { + return "4.7.1" + } + if releaseKey >= 460798 { + return "4.7" + } + if releaseKey >= 394802 { + return "4.6.2" + } + if releaseKey >= 394254 { + return "4.6.1" + } + if releaseKey >= 393295 { + return "4.6" + } + if releaseKey >= 379893 { + return "4.5.2" + } + if releaseKey >= 378675 { + return "4.5.1" + } + if releaseKey >= 378389 { + return "4.5" + } + // This code should never execute. A non-null release key should mean + // 安装4.5或更高版本。 + return "No 4.5 or later version detected" +} diff --git a/dotnet/dotnet_test.go b/dotnet/dotnet_test.go new file mode 100644 index 0000000..fed06d9 --- /dev/null +++ b/dotnet/dotnet_test.go @@ -0,0 +1,31 @@ +package dotnet + +import "testing" + +func TestCheckFor45PlusVersion(t *testing.T) { + cases := []struct { + release int + want string + }{ + {533320, "4.8.1 or later"}, + {533325, "4.8.1 or later"}, + {528040, "4.8"}, + {528049, "4.8"}, + {461808, "4.7.2"}, + {461308, "4.7.1"}, + {460798, "4.7"}, + {394802, "4.6.2"}, + {394254, "4.6.1"}, + {393295, "4.6"}, + {379893, "4.5.2"}, + {378675, "4.5.1"}, + {378389, "4.5"}, + {100000, "No 4.5 or later version detected"}, + {0, "No 4.5 or later version detected"}, + } + for _, c := range cases { + if got := CheckFor45PlusVersion(c.release); got != c.want { + t.Errorf("CheckFor45PlusVersion(%d) = %q, want %q", c.release, got, c.want) + } + } +} diff --git a/examples/dotnet/main.go b/examples/dotnet/main.go new file mode 100644 index 0000000..2baa13d --- /dev/null +++ b/examples/dotnet/main.go @@ -0,0 +1,26 @@ +// dotnet 包示例:读取本机 .NET Framework 安装信息(Windows 注册表) +package main + +import ( + "fmt" + + "git.zeroonesoft.cn/golib/zogo/dotnet" +) + +func main() { + // .NET Framework 4.x(读取 Release 注册表值) + if v4, err := dotnet.GetV4Info(); err != nil { + fmt.Println("未检测到 .NET Framework 4.x:", err) + } else { + fmt.Printf(".NET 4.x: Install=%d Version=%s Release=%d\n", v4.Install, v4.Version, v4.Release) + fmt.Println("4.5+ 版本判定:", dotnet.CheckFor45PlusVersion(int(v4.Release))) + } + + // 旧版本信息 + if v2, err := dotnet.GetV2Info(); err == nil { + fmt.Printf(".NET 2.0: Install=%d Version=%s\n", v2.Install, v2.Version) + } + if v35, err := dotnet.GetV35Info(); err == nil { + fmt.Printf(".NET 3.5: Install=%d Version=%s\n", v35.Install, v35.Version) + } +}