获取windows系统版本
项目地址
emm .... 我放在这里了
https://github.com/0xAAFF/WindowsVersion
具体判断函数
在 OSVersion() 判断操作系统
小节,判断逻辑都是一样的 ,可以直接跳过去看
这个函数判断了从 win nt 4 - win 11 之间的所有操作系统
但是没有写是home版本或者专业版本的判断.如果您有兴趣,可以自己添加
原理
使用windows API得到windwos的主版本号,次版本号,编译版本号,这样大概区分出windows的版本
然后根据各个版本号下的具体的属性再次细分得到是否为Server或者WorkStation
Windows8.1以下版本的API:
GetVersionExW()
Windwos8.1及以上的版本API:
RtlGetNtVersionNumbers() 和 GetVersionExW() 配合使用
注:为什么这样使用:
因为GetVersionExW()在windows8.1及以上获取的主版本号,次版本号和编译版本号都是一样的 :6.2.9200
但是获取的其他信息是对的.
所以,使用RtlGetNtVersionNumbers()这个API会得到正确的版本号.
当然,中间为了获取winxp64的,使用了GetNativeSystemInfo这个API来获取cpu的架构:ARCH=386可以执行 amd64获取的数据不对.请考虑使用
支持版本
/*
Windows NT 4
Windows 95
Windows 98
Windows Me
Windows 2000
Windows XP
Windows XP 64
Windows Server 2003
Windows Server 2003 R2
Windwos Vista
Windows Server 2008
Windwos 7
Windows Server 2008 R2
Windwos 8
Windows Server 2012
Windows 8.1
Windows Server 2012 R2
Windows 10
Windows Server 2016
Windows Server 2019
Windows 11
Windows 11 +
*/
具体实现
1 golang使用API需要用到一些数据类型,这里我的习惯是提取出来,这样方便使用.当然.每个人的习惯不同.
我定义了以下数据类型,不一定精确.如果有不正确的地方,请指正:
// go_type.go
package winapi_type
import (
"syscall"
"unicode/utf16"
"unsafe"
)
type HANDLE uintptr
type HMODULE uintptr
type LPVOID uintptr
type WORD uint16
type DWORD uint32
type DWORD_PTR uintptr // 不确定
type ULong uint32
type HRESULT uint32 // blog.csdn.net/ixsea/article/details/7272909
type LPBYTE *byte
type LPDWORD *uint32
type LPWSTR *uint16
type LMSTR *uint16
// type WCHAR = wchar_t
// type wchar_t = uint16
// UTF16toString converts a pointer to a UTF16 string into a Go string.
func UTF16toString(p *uint16) string {
return syscall.UTF16ToString((*[4096]uint16)(unsafe.Pointer(p))[:])
}
func StrPtr(s string) uintptr {
systemNameUTF16String, err := syscall.UTF16PtrFromString(s)
if err == nil {
// 这里转换的时候出错,则不继续执行 OR 赋值用本地的
tmp := utf16.Encode([]rune("\x00"))
systemNameUTF16String = &tmp[0]
}
return uintptr(unsafe.Pointer(systemNameUTF16String))
}
func CharsPtr(s string) uintptr {
bPtr, err := syscall.BytePtrFromString(s)
if err != nil {
return uintptr(0) // 这么写肯定不太对 @TODO
}
return uintptr(unsafe.Pointer(bPtr))
}
func IntPtr(n int) uintptr {
return uintptr(n)
}
2 常用操作系统量
// winnt.go
package version
// 判断操作系统的量
var (
PROCESSOR_ARCHITECTURE_INTEL = 0
PROCESSOR_ARCHITECTURE_MIPS = 1
PROCESSOR_ARCHITECTURE_ALPHA = 2
PROCESSOR_ARCHITECTURE_PPC = 3
PROCESSOR_ARCHITECTURE_SHX = 4
PROCESSOR_ARCHITECTURE_ARM = 5
PROCESSOR_ARCHITECTURE_IA64 = 6
PROCESSOR_ARCHITECTURE_ALPHA64 = 7
PROCESSOR_ARCHITECTURE_MSIL = 8
PROCESSOR_ARCHITECTURE_AMD64 = 9
PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 = 10
PROCESSOR_ARCHITECTURE_NEUTRAL = 11
PROCESSOR_ARCHITECTURE_ARM64 = 12
PROCESSOR_ARCHITECTURE_ARM32_ON_WIN64 = 13
PROCESSOR_ARCHITECTURE_IA32_ON_ARM64 = 14
PROCESSOR_ARCHITECTURE_UNKNOWN = 0xFFFF
PRODUCT_UNDEFINED = 0x00000000
PRODUCT_ULTIMATE = 0x00000001
PRODUCT_HOME_BASIC = 0x00000002
PRODUCT_HOME_PREMIUM = 0x00000003
PRODUCT_ENTERPRISE = 0x00000004
PRODUCT_HOME_BASIC_N = 0x00000005
PRODUCT_BUSINESS = 0x00000006
PRODUCT_STANDARD_SERVER = 0x00000007
PRODUCT_DATACENTER_SERVER = 0x00000008
PRODUCT_SMALLBUSINESS_SERVER = 0x00000009
PRODUCT_ENTERPRISE_SERVER = 0x0000000A
PRODUCT_STARTER = 0x0000000B
PRODUCT_DATACENTER_SERVER_CORE = 0x0000000C
PRODUCT_STANDARD_SERVER_CORE = 0x0000000D
PRODUCT_ENTERPRISE_SERVER_CORE = 0x0000000E
PRODUCT_ENTERPRISE_SERVER_IA64 = 0x0000000F
PRODUCT_BUSINESS_N = 0x00000010
PRODUCT_WEB_SERVER = 0x00000011
PRODUCT_CLUSTER_SERVER = 0x00000012
PRODUCT_HOME_SERVER = 0x00000013
PRODUCT_STORAGE_EXPRESS_SERVER = 0x00000014
PRODUCT_STORAGE_STANDARD_SERVER = 0x00000015
PRODUCT_STORAGE_WORKGROUP_SERVER = 0x00000016
PRODUCT_STORAGE_ENTERPRISE_SERVER = 0x00000017
PRODUCT_SERVER_FOR_SMALLBUSINESS = 0x00000018
PRODUCT_SMALLBUSINESS_SERVER_PREMIUM = 0x00000019
PRODUCT_UNLICENSED = uint64(0xABCDABCD)
VER_PLATFORM_WIN32s = 0
VER_PLATFORM_WIN32_WINDOWS = 1
VER_PLATFORM_WIN32_NT = 2
VER_NT_WORKSTATION = 0x0000001
VER_NT_DOMAIN_CONTROLLER = 0x0000002
VER_NT_SERVER = 0x0000003
//#if(_WIN32_WINNT >= 0x0501)
SM_TABLETPC = 86
SM_MEDIACENTER = 87
SM_STARTER = 88
SM_SERVERR2 = 89
//#endif /* _WIN32_WINNT >= 0x0501 */
)
3 GetVersionExW 的API调用及使用的数据结构
// under_8.1version_windows.go
package version
import (
"syscall"
"unsafe"
. "wxw.test.x/system/windows/winapi_type"
)
//
// GetVersionExA 函数 (sysinfoapi.h)
// Kernel32.lib
// 最低支持 Windows 2000 Professional/Server [desktop apps | UWP apps]
// docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getversionexa
// #region GetVersionExW 函数 (sysinfoapi.h)
// docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getversionexw
/*
Kernel32.dll
GetVersionExW function (sysinfoapi.h)
NOT_BUILD_WINDOWS_DEPRECATE BOOL GetVersionExW(
[in, out] LPOSVERSIONINFOW lpVersionInformation
);
*/
func GetVersionExW() (OSVersionInfoExA, error) {
//csdVer := make([]byte, 128)
var osVersionInfoExA OSVersionInfoExA
// osVersionInfoExA := OSVersionInfoExA{
// //CSDVersion: csdVer, //uintptr(unsafe.Pointer(&csdVer[0])), //StrPtr(csdVer), //csdVer[:128], //uintptr(unsafe.Pointer(&csdVer[0])),
// }
osVersionInfoExA.OSVersionInfoSize = DWORD(unsafe.Sizeof(osVersionInfoExA))
kernel32 := syscall.NewLazyDLL("Kernel32.dll")
procGetVersionExW := kernel32.NewProc("GetVersionExA")
_, _, err := procGetVersionExW.Call(uintptr(unsafe.Pointer(&osVersionInfoExA)))
//v, vv, err := procGetVersionExW.Call(uintptr(unsafe.Pointer(&osVersionInfoExA)))
// fmt.Println(v)
// fmt.Println(vv)
// fmt.Println(err)
if err != nil && err.Error() == "The operation completed successfully." {
err = nil
}
// fmt.Println("-----------------GetVersionExW-----------------")
// fmt.Printf("%#v \n", osVersionInfoExA)
// fmt.Println("主版本 :", osVersionInfoExA.MajorVersion)
// fmt.Println("次版本 :", osVersionInfoExA.MinorVersion)
// fmt.Println("编译版本 :", osVersionInfoExA.BuildNumber)
// fmt.Println("操作系统平台 :", osVersionInfoExA.PlatformId)
// fmt.Println("SP(主) :", osVersionInfoExA.MajorVersion)
// fmt.Println("SP(次) :", osVersionInfoExA.ServicePackMinor)
return osVersionInfoExA, err
}
// # endregion
// #region OSVERSIONINFOEXA structure
// docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-osversioninfoexa
/*
typedef struct _OSVERSIONINFOEXA {
DWORD dwOSVersionInfoSize;
DWORD dwMajorVersion;
DWORD dwMinorVersion;
DWORD dwBuildNumber;
DWORD dwPlatformId;
CHAR szCSDVersion[128];
WORD wServicePackMajor;
WORD wServicePackMinor;
WORD wSuiteMask;
BYTE wProductType;
BYTE wReserved;
} OSVERSIONINFOEXA, *POSVERSIONINFOEXA, *LPOSVERSIONINFOEXA;
*/
type OSVersionInfoExA struct {
OSVersionInfoSize DWORD // 结构体大小, in bytes. Set this member to sizeof(OSVERSIONINFOEX).
MajorVersion DWORD // 主版本号
MinorVersion DWORD // 次版本号
BuildNumber DWORD // 编译版本号
PlatformId DWORD // 系统支持的平台
CSDVersion [128]byte // 系统补丁包的名称 CSDVersion[128]// 这个128是必须的 不然就会出现"The data area passed to a system call is too small."
ServicePackMajor WORD // 系统补丁包的主版本
ServicePackMinor WORD // 系统补丁包的次版本
SuiteMask WORD // 标识系统上的程序组
ProductType byte // 标识系统类型
Reserved byte // 保留,未使用
} // 这个结构在Windows 2000后出现,老版本的OSVERSIONINFO结构没有wServicePackMajor、wServicePackMinor、wSuiteMask、wProductType和wReserved这几个成员。
// #endregion
// #region OSVERSIONINFOA
// OSVERSIONINFOA structure (winnt.h)
// docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-osversioninfoa
/*
typedef struct _OSVERSIONINFOA {
DWORD dwOSVersionInfoSize;
DWORD dwMajorVersion;
DWORD dwMinorVersion;
DWORD dwBuildNumber;
DWORD dwPlatformId;
CHAR szCSDVersion[128];
} OSVERSIONINFOA, *POSVERSIONINFOA, *LPOSVERSIONINFOA;
*/
type OSVersionInfoA struct {
OSVersionInfoSize DWORD // 结构体大小, in bytes. Set this member to sizeof(OSVERSIONINFOEX).
MajorVersion DWORD // 主版本号
MinorVersion DWORD // 次版本号
BuildNumber DWORD // 编译版本号
PlatformId DWORD // 系统支持的平台
CSDVersion [128]byte // 系统补丁包的名称 CSDVersion[128]
}
// #endregion
// Version Helper functions
// Windwos 系统版本助手(微软官方推荐此函数列表)
// docs.microsoft.com/en-us/windows/win32/sysinfo/version-helper-apis
// 但是我没用 - -
// IsWow64Process函数
// GetNativeSystemInfo function (sysinfoapi.h)
// docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getnativesysteminfo
4 GetNativeSystemInfo() 的API的调用
go env -w GOARCH=386
时可以调用成功,但是GOARCH=amd64时调用数据是不对的,如果您发现了这个问题的解决方式,请联系我
// systeminfo_windows.go
package version
import (
"syscall"
"unsafe"
. "x.test.x/system/windows/winapi_type" // 这里我手动修改了下,请在您的项目中注意引用
)
// api dll
// Kernel32.dll
// Kernel32 := syscall.NewLazyDLL("kernel32.dll")
// 判断windwos操作系统是32位还是64位
// GetNativeSystemInfo function (sysinfoapi.h)
// docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getnativesysteminfo
/*
void GetNativeSystemInfo(
[out] LPSYSTEM_INFO lpSystemInfo
);
*/
func GetNativeSystemInfo() (*SystemInfo, error) {
kernel32 := syscall.NewLazyDLL("kernel32.dll")
procGetNativeSystemInfo := kernel32.NewProc("GetNativeSystemInfo")
systemInformation := &SystemInfo{}
_, _, err := procGetNativeSystemInfo.Call(uintptr(unsafe.Pointer(systemInformation)))
if err != nil && err.Error() == "The operation completed successfully." {
err = nil
}
// fmt.Println(err)
// fmt.Printf("%#v \n", systemInformation)
// fmt.Printf("%#v \n", systemInformation.DummyUnionName)
// dummyStructName := (*DummyStructName)(unsafe.Pointer(&systemInformation.DummyUnionName))
// fmt.Printf("dummyStructName : %#v \n", dummyStructName)
// fmt.Println("架构 : ", dummyStructName.Architecture())
// fmt.Println("处理器数量 : ", systemInformation.NumberOfProcessors)
// fmt.Println("处理器类型 : ", systemInformation.ProcessorType)
return systemInformation, err
}
// 参数
// SYSTEM_INFO structure (sysinfoapi.h)
// docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info
/*
// DUMMYUNIONNAME
/*
struct {
WORD wProcessorArchitecture;
WORD wReserved;
} DUMMYSTRUCTNAME;
} DUMMYUNIONNAME;
*/
// DummyStructName 虚拟结构名
type DummyStructName struct {
/*
ProcessorArchitecture 值和说明
--------------------------------|--------------------------------|
Value | Meaning
--------------------------------|--------------------------------|
PROCESSOR_ARCHITECTURE_AMD64 | x64 (AMD or Intel)
9 |
--------------------------------|--------------------------------|
PROCESSOR_ARCHITECTURE_ARM | ARM
5 |
--------------------------------|--------------------------------|
PROCESSOR_ARCHITECTURE_ARM64 | ARM64
12 |
--------------------------------|--------------------------------|
PROCESSOR_ARCHITECTURE_IA64 | Intel Itanium-based
6 |
--------------------------------|--------------------------------|
PROCESSOR_ARCHITECTURE_INTEL | x86
0 |
--------------------------------|--------------------------------|
PROCESSOR_ARCHITECTURE_UNKNOWN | 未知架构
0xffff |
--------------------------------|--------------------------------|
*/
ProcessorArchitecture WORD // 已安装操作系统的处理器体系结构。
Reserved WORD
}
// OemId
type OemId struct {
OemId DWORD
}
/*
When `go env -w GOARCH=amd64`: NumberOfProcessors:0x10000,ProcessorType:0x7e050006,(Error.不是太清楚这个什么原因):
&version.SystemInfo{DummyUnionName:0x100000000009, PageSize:0x10000, MinimumApplicationAddress:0x7ffffffeffff, MaximumApplicationAddress:0xff, ActiveProcessorMask:0x21d800000008, NumberOfProcessors:0x10000, ProcessorType:0x7e050006, AllocationGranularity:0x0, ProcessorLevel:0x0, ProcessorRevision:0x0}
When `go env -w GOARCH=386` : NumberOfProcessors:0x8, ProcessorType:0x21d8 (correct 这个才是正确的):
&version.SystemInfo{DummyUnionName:0x9, PageSize:0x1000, MinimumApplicationAddress:0x10000, MaximumApplicationAddress:0xfffeffff, ActiveProcessorMask:0xff, NumberOfProcessors:0x8, ProcessorType:0x21d8, AllocationGranularity:0x10000, ProcessorLevel:0x6, ProcessorRevision:0x7e05}
*/
/*
// 参数类型
typedef struct _SYSTEM_INFO {
union {
DWORD dwOemId;
struct {
WORD wProcessorArchitecture;
WORD wReserved;
} DUMMYSTRUCTNAME;
} DUMMYUNIONNAME;
DWORD dwPageSize;
LPVOID lpMinimumApplicationAddress;
LPVOID lpMaximumApplicationAddress;
DWORD_PTR dwActiveProcessorMask;
DWORD dwNumberOfProcessors;
DWORD dwProcessorType;
DWORD dwAllocationGranularity;
WORD wProcessorLevel;
WORD wProcessorRevision;
} SYSTEM_INFO, *LPSYSTEM_INFO;
*/
type SystemInfo struct {
DummyUnionName uintptr //DummyUnionName Or OemId ,one of this Use Same Memory.两个结构使用同一块内存
PageSize DWORD // 虚拟内存页的大小
MinimumApplicationAddress LPVOID // 应用程序和动态链接库(DLL)可访问的最低内存地址
MaximumApplicationAddress LPVOID // 应用程序和动态链接库(DLL)可访问的最高内存地址
ActiveProcessorMask DWORD_PTR // 表示配置到系统中的处理器集的掩码
NumberOfProcessors DWORD // 处理器数量
ProcessorType DWORD // 处理器类型
AllocationGranularity DWORD // 虚拟内存的起始地址
ProcessorLevel WORD // 依赖于体系结构的处理器级别。它只能用于显示目的。要确定处理器的功能集,请使用IsProcessorFeaturePresent函数。
ProcessorRevision WORD // 依赖于体系结构的处理器版本
}
// 当前系统中的中央处理器的架构
func (d *DummyStructName) Architecture() string {
switch d.ProcessorArchitecture {
case 0:
{
return "x86" // 32位
}
case 5:
{
return "ARM" // 32位
}
case 6:
{
return "Itanium" //Intel Itanium-based // Intel 奔腾架构 32位处理器
}
case 9:
{
return "x64" // (AMD or Intel) 64位处理器
}
case 12:
{
return "ARM64" // 64位处理器
}
case 0xffff:
{
return "Unknow" // 未知
}
default:
{
return "Unknow" // 未知
}
}
}
// 是否为64位操作系统
func (d *DummyStructName) IsWin64() bool {
return d.ProcessorArchitecture == WORD(PROCESSOR_ARCHITECTURE_AMD64) || d.ProcessorArchitecture == WORD(PROCESSOR_ARCHITECTURE_IA64)
}
// 处理器类型
// PROCESSOR_INTEL_386 (386)
// PROCESSOR_INTEL_486 (486)
// PROCESSOR_INTEL_PENTIUM (586)
// PROCESSOR_INTEL_IA64 (2200)
// PROCESSOR_AMD_X8664 (8664)
// PROCESSOR_ARM (Reserved)
func (s *SystemInfo) GetProcessorType() string {
switch s.ProcessorType {
case 386: // 0x0182
{
return "386"
}
case 486: // 0x01E6
{
return "486"
}
case 586: // 0x024A
{
return "Pentium" // "奔腾"
}
case 2200: // 0x0898
{
return "Itanium" //"安腾"
}
case 8664: // 0x21D8
{
return "X8664" //
}
// case xxx{ return "ARM" }
default:
{
return "Unknow"
}
}
}
func (s *SystemInfo) GetDummyStructName() *DummyStructName {
dummyStructName := (*DummyStructName)(unsafe.Pointer(&s.DummyUnionName))
// fmt.Printf("dummyStructName : %#v \n", dummyStructName)
// fmt.Println("架构 : ", dummyStructName.Architecture())
// fmt.Println("处理器数量 : ", s.NumberOfProcessors)
// fmt.Println("处理器类型 : ", s.ProcessorType)
return dummyStructName
}
5 GetSystemMetrics()的API的调用
// system_metrics_windows.go
package version
import (
"syscall"
)
// GetSystemMetrics function (winuser.h)
// User32.dll
// docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsystemmetrics
/*
int GetSystemMetrics(
[in] int nIndex
);
*/
func GetSystemMetrics(index int) (int, error) {
user32 := syscall.NewLazyDLL("User32.dll")
procGetSystemMetrics := user32.NewProc("GetSystemMetrics")
v, _, err := procGetSystemMetrics.Call(uintptr(index))
// fmt.Printf("%#v \n", v)
// fmt.Println(err)
return int(v), err
}
6 OSVersion() 判断操作系统
// osversion_windows.go
package version
import (
"syscall"
"unsafe"
)
/*
Windows NT 4
Windows 95
Windows 98
Windows Me
Windows 2000
Windows XP
Windows XP 64
Windows Server 2003
Windows Server 2003 R2
Windwos Vista
Windows Server 2008
Windwos 7
Windows Server 2008 R2
Windwos 8
Windows Server 2012
Windows 8.1
Windows Server 2012 R2
Windows 10
Windows Server 2016
Windows Server 2019
Windows 11
Windows 11 +
*/
func OSVersion() (string, error) {
// 以下代码获取windows8.1及以上的操作系统
majorVersion, minorVersion, buildNumber := RtlGetNtVersionNumbers()
// fmt.Printf("majorVersion:%d ,minorVersion:%d ,buildNumber:%d \n", majorVersion, minorVersion, buildNumber)
o, err := GetVersionExW()
if err != nil {
// fmt.Println("GetVersionExW : ", err)
return "", err
}
/*
Windows 8.1
Windows 10
Windows Server 2016
Windows Server 2019
Windows 11
Windows 11 +
*/
// GetVersionExW : win8.1+ :> 6.2.9200 ()
if majorVersion > 6 || (majorVersion == 6 && minorVersion >= 3) { // win8plus
if majorVersion == 6 && minorVersion >= 3 {
// Win8.1 : 6.3.9600
// Windows Server 2012
if o.ProductType == byte(VER_NT_WORKSTATION) {
return "Windows 8.1", nil
} else {
// fmt.Println("o.ProductType :", o.ProductType)
return "Windows Server 2012 R2", nil
}
} else if majorVersion == 10 && minorVersion == 0 {
// Win 10 :10.0.19042
// WinSer 2019 :10.0.17763
// Win 11 :10.0.22000
if o.ProductType == byte(VER_NT_WORKSTATION) {
if buildNumber >= 22000 {
return "Windows 11", nil
} else { // if buildNumber >= 18363 {
// 18363 : Win10 专业版
// 19041 : win10 家庭中文版
// 19042 : win10 家庭中文版,教育版
// 19043 : win10 专业版
return "Windows 10", nil
}
} else {
if buildNumber >= 17763 {
return "Windows Server 2019", nil
} else if buildNumber >= 14393 {
return "Windows Server 2016", nil
}
}
} else {
return "Windows 11 +", nil
}
}
// 以下代码获取windows 8.1一下的系统版本
/*
Windows NT 4
Windows 95
Windows 98
Windows Me
Windows 2000
Windows XP
Windows XP 64
Windows Server 2003
Windows Server 2003 R2
Windwos Vista
Windows Server 2008
Windwos 7
Windows Server 2008 R2
Windwos 8
Windows Server 2012
*/
s, err := GetNativeSystemInfo()
if err != nil {
return "", nil
}
u := s.GetDummyStructName()
switch o.MajorVersion {
case 4:
{
switch o.MinorVersion {
case 0:
{
if int(o.PlatformId) == VER_PLATFORM_WIN32_NT {
return "Windows NT 4", nil
} else if int(o.PlatformId) == VER_PLATFORM_WIN32_WINDOWS {
return "Windows 95", nil
}
}
case 10:
{
return "Windows 98", nil
}
case 90:
{
return "Windows Me", nil
}
}
}
case 5:
{
switch o.MinorVersion {
case 0:
{
return "Windows 2000", nil
}
case 1:
{
return "Windows XP", nil
}
case 2:
{
r2, err := GetSystemMetrics(SM_SERVERR2)
if err != nil {
return "", err
}
if o.ProductType == byte(VER_NT_WORKSTATION) && u.IsWin64() {
return "Windows XP 64", nil
} else if r2 == 0 {
return "Windows Server 2003", nil
} else if r2 != 0 {
return "Windows Server 2003 R2", nil
}
}
}
}
case 6:
{
switch o.MinorVersion {
case 0:
{
if o.ProductType == byte(VER_NT_WORKSTATION) {
return "Windwos Vista", nil
} else {
return "Windows Server 2008", nil
}
}
case 1:
{
if o.ProductType == byte(VER_NT_WORKSTATION) {
return "Windwos 7", nil
} else {
return "Windows Server 2008 R2", nil
}
}
case 2:
{
if o.ProductType == byte(VER_NT_WORKSTATION) {
return "Windwos 8", nil
} else {
return "Windows Server 2012", nil
}
}
}
}
}
return "windows", nil
}
// Dll: ntdll.dll
// RtlGetNtVersionNumbers
// 获取系统的版本号
/*
HINSTANCE hinst = LoadLibrary("ntdll.dll");
DWORD dwMajor,dwMinor,dwBuildNumber;
NTPROC proc = (NTPROC)GetProcAddress(hinst,"RtlGetNtVersionNumbers");
proc(&dwMajor,&dwMinor,&dwBuildNumber);
dwBuildNumber&=0xffff;
*/
func RtlGetNtVersionNumbers() (majorVersion, minorVersion, buildNumber uint32) {
//var majorVersion, minorVersion, buildNumber uint32
ntdll := syscall.NewLazyDLL("ntdll.dll")
procRtlGetNtVersionNumbers := ntdll.NewProc("RtlGetNtVersionNumbers")
//v, vv, err := procRtlGetNtVersionNumbers.Call(
procRtlGetNtVersionNumbers.Call(
uintptr(unsafe.Pointer(&majorVersion)),
uintptr(unsafe.Pointer(&minorVersion)),
uintptr(unsafe.Pointer(&buildNumber)),
)
// fmt.Printf("%#v \n", v)
// fmt.Printf("%#v \n", vv)
// fmt.Printf("%#v \n", err)
// fmt.Println("开发版本:", buildNumber)
buildNumber &= 0xffff
// fmt.Println("-----------------RtlGetNtVersionNumbers-----------------")
// fmt.Println("主版本号:", majorVersion)
// fmt.Println("次版本号:", minorVersion)
// fmt.Println("开发版本:", buildNumber)
return
}
结束
以上代码,如果有疑问或者代码出现失误,请您及时联系我修改
简略不精准的代码 建议参考,不要使用:
下面的代码原理很简单,就是打开cmd,获取windows的cmd的[x.x.xxxx]的版本号截取下来,然后做匹配.这样虽然也行但是无法区分是否为服务器:
// OSVersion 获取windows版本号
func OSVersion() (string, error) {
// www.lifewire.com/what-version-of-windows-do-i-have-2624927 And bing.com search Images
versionNumbers := map[string]string{
`5.0`: "Win 2000", // Win2000 Microsoft Windows 2000 [Version 5.00.2195]
`5.1`: "Win XP", // WinXP 32 Microsoft Windows XP [Version 5.1.2600] Windows XP is the name given to Windows version 5.1.
`5.2`: "Win XP_64/Win Server 2003/Win Server 2003 R2", // WinXP 64 Microsoft Windows XP [Version 5.2] Windows version 5.2.
`6.0`: "Win Vista/Win Server 2008", // Win Vista Microsoft Windows [Version 6.0.6000] Windows Vista is the name given to Windows version 6.0.
`6.1`: "Win 7/Win Server 2008 R2", // Win7 Microsoft Windows [Version 6.1.7601] Windows 7 is the name given to Windows version 6.1.
`6.2`: "Win 8/Win Server 2012", // Win8 Microsoft Windows [Version 6.2.9200] Windows 8 is the name given to Windows version 6.2.
`6.3`: "Win 8.1/Win Server 2012 R2/Win Phone 8.1", // Win8.1 Microsoft Windows [Version 6.3.9600] Windows 8.1 is the name given to Windows version 6.3.
`6.4`: "Win 10(技术预览版)", // Win8.1 Microsoft Windows [Version 6.3.9600] Windows 8.1 is the name given to Windows version 6.3.
`10.0.22000.282`: "Win 11", // Win 11 当前
`10.0`: "Win 10/Win 11", // Win10 Microsoft Windows [Version 10.0.18363.1316] Windows 10 is the name given to Windows version 10.0 and is the latest version of Windows.
}
//Microsoft Windows [版本 6.1.7601] Win7
//Microsoft Windows [版本 10.0.18363.1316] Win 10
//Microsoft Windows [版本 10.0.17763.1935] Win Server 2019
cmd := exec.Command("cmd.exe")
out, _ := cmd.StdoutPipe()
buffer := bytes.NewBuffer(make([]byte, 0))
cmd.Start()
buffer.ReadFrom(out)
cmdText, err := buffer.ReadString(']')
cmd.Wait()
if err != nil {
return "", err
}
point := strings.Index(cmdText, "[")
if point < 0 {
return "", fmt.Errorf("cmd text error:[no '['] =>%s", cmdText)
}
cmdText = cmdText[point:]
point = strings.Index(cmdText, " ")
if point < 0 {
return "", fmt.Errorf("cmd text error:[no '['] =>%s", cmdText)
}
cmdText = cmdText[point+1 : len(cmdText)-1]
for key, _ := range versionNumbers {
if strings.HasPrefix(cmdText, key) {
return versionNumbers[key], nil
}
}
return "", fmt.Errorf("can not support this windows version")
}