獲取windows系統(tǒng)版本
項目地址
emm .... 我放在這里了
https://github.com/0xAAFF/WindowsVersion
具體判斷函數(shù)
在 OSVersion() 判斷操作系統(tǒng)小節(jié),判斷邏輯都是一樣的 ,可以直接跳過去看
這個函數(shù)判斷了從 win nt 4 - win 11 之間的所有操作系統(tǒng)
但是沒有寫是home版本或者專業(yè)版本的判斷.如果您有興趣,可以自己添加
原理
使用windows API得到windwos的主版本號,次版本號,編譯版本號,這樣大概區(qū)分出windows的版本
然后根據(jù)各個版本號下的具體的屬性再次細(xì)分得到是否為Server或者WorkStation
Windows8.1以下版本的API:
GetVersionExW()
Windwos8.1及以上的版本API:
RtlGetNtVersionNumbers() 和 GetVersionExW() 配合使用
注:為什么這樣使用:
因為GetVersionExW()在windows8.1及以上獲取的主版本號,次版本號和編譯版本號都是一樣的 :6.2.9200
但是獲取的其他信息是對的.
所以,使用RtlGetNtVersionNumbers()這個API會得到正確的版本號.
當(dāng)然,中間為了獲取winxp64的,使用了GetNativeSystemInfo這個API來獲取cpu的架構(gòu):ARCH=386可以執(zhí)行 amd64獲取的數(shù)據(jù)不對.請考慮使用
支持版本
/*
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 +
*/
具體實現(xiàn)
1 golang使用API需要用到一些數(shù)據(jù)類型,這里我的習(xí)慣是提取出來,這樣方便使用.當(dāng)然.每個人的習(xí)慣不同.
我定義了以下數(shù)據(jù)類型,不一定精確.如果有不正確的地方,請指正:
// 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 {
// 這里轉(zhuǎn)換的時候出錯,則不繼續(xù)執(zhí)行 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 常用操作系統(tǒng)量
// winnt.go
package version
// 判斷操作系統(tǒng)的量
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調(diào)用及使用的數(shù)據(jù)結(jié)構(gòu)
// under_8.1version_windows.go
package version
import (
"syscall"
"unsafe"
. "wxw.test.x/system/windows/winapi_type"
)
//
// GetVersionExA 函數(shù) (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 函數(shù) (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("操作系統(tǒng)平臺 :", 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 // 結(jié)構(gòu)體大小, in bytes. Set this member to sizeof(OSVERSIONINFOEX).
MajorVersion DWORD // 主版本號
MinorVersion DWORD // 次版本號
BuildNumber DWORD // 編譯版本號
PlatformId DWORD // 系統(tǒng)支持的平臺
CSDVersion [128]byte // 系統(tǒng)補(bǔ)丁包的名稱 CSDVersion[128]// 這個128是必須的 不然就會出現(xiàn)"The data area passed to a system call is too small."
ServicePackMajor WORD // 系統(tǒng)補(bǔ)丁包的主版本
ServicePackMinor WORD // 系統(tǒng)補(bǔ)丁包的次版本
SuiteMask WORD // 標(biāo)識系統(tǒng)上的程序組
ProductType byte // 標(biāo)識系統(tǒng)類型
Reserved byte // 保留,未使用
} // 這個結(jié)構(gòu)在Windows 2000后出現(xiàn),老版本的OSVERSIONINFO結(jié)構(gòu)沒有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 // 結(jié)構(gòu)體大小, in bytes. Set this member to sizeof(OSVERSIONINFOEX).
MajorVersion DWORD // 主版本號
MinorVersion DWORD // 次版本號
BuildNumber DWORD // 編譯版本號
PlatformId DWORD // 系統(tǒng)支持的平臺
CSDVersion [128]byte // 系統(tǒng)補(bǔ)丁包的名稱 CSDVersion[128]
}
// #endregion
// Version Helper functions
// Windwos 系統(tǒng)版本助手(微軟官方推薦此函數(shù)列表)
// docs.microsoft.com/en-us/windows/win32/sysinfo/version-helper-apis
// 但是我沒用 - -
// IsWow64Process函數(shù)
// GetNativeSystemInfo function (sysinfoapi.h)
// docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getnativesysteminfo
4 GetNativeSystemInfo() 的API的調(diào)用
go env -w GOARCH=386 時可以調(diào)用成功,但是GOARCH=amd64時調(diào)用數(shù)據(jù)是不對的,如果您發(fā)現(xiàn)了這個問題的解決方式,請聯(lián)系我
// 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操作系統(tǒng)是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("架構(gòu) : ", dummyStructName.Architecture())
// fmt.Println("處理器數(shù)量 : ", systemInformation.NumberOfProcessors)
// fmt.Println("處理器類型 : ", systemInformation.ProcessorType)
return systemInformation, err
}
// 參數(shù)
// 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 虛擬結(jié)構(gòu)名
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 | 未知架構(gòu)
0xffff |
--------------------------------|--------------------------------|
*/
ProcessorArchitecture WORD // 已安裝操作系統(tǒng)的處理器體系結(jié)構(gòu)。
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}
*/
/*
// 參數(shù)類型
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.兩個結(jié)構(gòu)使用同一塊內(nèi)存
PageSize DWORD // 虛擬內(nèi)存頁的大小
MinimumApplicationAddress LPVOID // 應(yīng)用程序和動態(tài)鏈接庫(DLL)可訪問的最低內(nèi)存地址
MaximumApplicationAddress LPVOID // 應(yīng)用程序和動態(tài)鏈接庫(DLL)可訪問的最高內(nèi)存地址
ActiveProcessorMask DWORD_PTR // 表示配置到系統(tǒng)中的處理器集的掩碼
NumberOfProcessors DWORD // 處理器數(shù)量
ProcessorType DWORD // 處理器類型
AllocationGranularity DWORD // 虛擬內(nèi)存的起始地址
ProcessorLevel WORD // 依賴于體系結(jié)構(gòu)的處理器級別。它只能用于顯示目的。要確定處理器的功能集,請使用IsProcessorFeaturePresent函數(shù)。
ProcessorRevision WORD // 依賴于體系結(jié)構(gòu)的處理器版本
}
// 當(dāng)前系統(tǒng)中的中央處理器的架構(gòu)
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 奔騰架構(gòu) 32位處理器
}
case 9:
{
return "x64" // (AMD or Intel) 64位處理器
}
case 12:
{
return "ARM64" // 64位處理器
}
case 0xffff:
{
return "Unknow" // 未知
}
default:
{
return "Unknow" // 未知
}
}
}
// 是否為64位操作系統(tǒng)
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("架構(gòu) : ", dummyStructName.Architecture())
// fmt.Println("處理器數(shù)量 : ", s.NumberOfProcessors)
// fmt.Println("處理器類型 : ", s.ProcessorType)
return dummyStructName
}
5 GetSystemMetrics()的API的調(diào)用
// 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() 判斷操作系統(tǒng)
// 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及以上的操作系統(tǒng)
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 專業(yè)版
// 19041 : win10 家庭中文版
// 19042 : win10 家庭中文版,教育版
// 19043 : win10 專業(yè)版
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一下的系統(tǒng)版本
/*
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
// 獲取系統(tǒng)的版本號
/*
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("開發(fā)版本:", buildNumber)
buildNumber &= 0xffff
// fmt.Println("-----------------RtlGetNtVersionNumbers-----------------")
// fmt.Println("主版本號:", majorVersion)
// fmt.Println("次版本號:", minorVersion)
// fmt.Println("開發(fā)版本:", buildNumber)
return
}
結(jié)束
以上代碼,如果有疑問或者代碼出現(xiàn)失誤,請您及時聯(lián)系我修改
簡略不精準(zhǔn)的代碼 建議參考,不要使用:
下面的代碼原理很簡單,就是打開cmd,獲取windows的cmd的[x.x.xxxx]的版本號截取下來,然后做匹配.這樣雖然也行但是無法區(qū)分是否為服務(wù)器:
// 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(技術(shù)預(yù)覽版)", // 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 當(dāng)前
`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")
}