Jump to content

Search the Community

Showing results for tags '_getosversiondetailed'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • General
    • Announcements and Site News
    • Administration
  • AutoIt v3
    • AutoIt Help and Support
    • AutoIt Technical Discussion
    • AutoIt Example Scripts
  • Scripting and Development
    • Developer General Discussion
    • Language Specific Discussion
  • IT Administration
    • Operating System Deployment
    • Windows Client
    • Windows Server
    • Office

Categories

  • AutoIt Team
    • Beta
    • MVP
  • AutoIt
    • Automation
    • Databases and web connections
    • Data compression
    • Encryption and hash
    • Games
    • GUI Additions
    • Hardware
    • Information gathering
    • Internet protocol suite
    • Maths
    • Media
    • PDF
    • Security
    • Social Media and other Website API
    • Windows
  • Scripting and Development
  • IT Administration
    • Operating System Deployment
    • Windows Client
    • Windows Server
    • Office

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Member Title


Location


WWW


Interests

Found 1 result

  1. UDF: #include-once ; #INDEX# ======================================================================================================================= ; Title ..........: Windows Version Detector UDF v5 ; AutoIt Version .: 3.3.16.1+ ; Language .......: English ; Description ...: This User Defined Function (UDF) detects Windows versions for both live (running) and offline (mounted or extracted) Windows installations. ; It uses a dual-database approach: an exact build database for precise matches and a range-based inference database for broader version identification. ; The UDF supports Windows from version 1.0 up to Windows Server 2025, including client and server editions, Insider previews, and various builds. ; Key features include registry reading for live systems, offline hive loading for mounted images, and file-based fallback detection. ; Author(s) ......: Dao Van Trong - TRONG.PRO ; Version ........: 3.8.1 (Updated for consistent official version names like 2004; Enhanced with full UDF headers and inline comments) ; Dll(s) .........: kernel32.dll, advapi32.dll, ole32.dll ; =============================================================================================================================== ; #INCLUDES# ==================================================================================================================== #include <FileConstants.au3> ; For file operations like $OPEN_EXISTING, $FILE_SHARE_READ, $GENERIC_READ #include <APIRegConstants.au3> ; For registry constants like $HKEY_LOCAL_MACHINE #include <APIErrorsConstants.au3> ; For error codes like $ERROR_SUCCESS #include <StringConstants.au3> ; For string manipulation constants like $STR_STRIPLEADING, $STR_STRIPTRAILING, $STR_NOCOUNT #include <Array.au3> ; For array functions like _ArrayToString (though custom implementation used here for compatibility) ; =============================================================================================================================== ; #CONSTANTS# ==================================================================================================================== ; Registry paths and system constants Global Const $REG_KEY_VERSION = "SOFTWARE\Microsoft\Windows NT\CurrentVersion" ; Main registry key for Windows version info Global Const $REG_KEY_INSIDER = "SOFTWARE\Microsoft\WindowsSelfHost\Applicability" ; Registry key for Insider preview detection Global Const $HIVE_SOFTWARE = "\System32\Config\SOFTWARE" ; Path to SOFTWARE hive file for offline detection Global Const $MAX_PATH = 32767 ; Maximum path length for Windows API calls Global Const $SE_BACKUP_PRIVILEGE = "SeBackupPrivilege" ; Privilege required to load/unload registry hives ; Static version databases (initialized at compile time) ; Range DB structure: [MinBuild, MaxBuild, ProductName] - Used for inferring versions when exact match fails Global Const $_g_aWinVerRangeDB = __WinVerDetect_InitWindowsVersionDB() ; Exact DB structure: [ProductName, Codename, ReleaseDate, DisplayVersion, Build, UBR] - For precise version matching Global Const $_g_aWinVerExactDB = __WinVerDetect_InitExactWindowsVersionDB() ; Edition mappings array Global Const $g_aEditionMap = __WinVerDetect_InitEditionMap() ; =============================================================================================================================== ; #ENUMS# ======================================================================================================================= ; Enum for return array indices from _WinVerDetect_GetVersion (when $iReturn = -1) Global Enum $WINVER_STATE, _ ; 0: "Live" or "Offline" indicating if the system is running or not $WINVER_SHORTNAME, _ ; 1: Short OS identifier (e.g., "WIN_10", "WIN_11", "WIN_SRV") $WINVER_PRODUCTNAME, _ ; 2: Full product name (e.g., "Windows 10", "Windows Server 2022") $WINVER_FULLNAME, _ ; 3: Full version name (e.g., "Windows 10 Version 22H2 (Build 19045)") $WINVER_BUILD, _ ; 4: Major build number (e.g., "19045") $WINVER_UBR, _ ; 5: Update Build Revision (e.g., "4567") $WINVER_DISPLAYVERSION, _ ; 6: Display version string (e.g., "22H2", "2004") $WINVER_EDITIONID, _ ; 7: Edition ID (e.g., "Professional", "Enterprise", "Server") $WINVER_EDITIONTYPE, _ ; 8: Inferred edition type (e.g., "Professional") $WINVER_ISINSIDER ; 9: Boolean (True if Insider Preview) ; Enum for error codes returned by @error in _WinVerDetect_GetVersion Global Enum $WINVER_ERROR_SUCCESS, _ ; 0: No error $WINVER_ERROR_INVALID_PATH, _ ; 1: Invalid or non-existent Windows path $WINVER_ERROR_REGISTRY_FAILED, _ ; 2: Failed to read registry (live or offline) $WINVER_ERROR_FILE_ACCESS, _ ; 3: File access denied or files not found $WINVER_ERROR_NO_ADMIN, _ ; 4: Admin privileges required for live/offline operations $WINVER_ERROR_INVALID_BUILD ; 5: Invalid or unrecognized build number ; =============================================================================================================================== ; #VARIABLES# ==================================================================================================================== ; No global variables beyond constants; all data is in static arrays for efficiency ; =============================================================================================================================== ; #FUNCTIONS# ==================================================================================================================== ; Public Functions ; _WinVerDetect_GetVersion ; _RegReadMulti ; =============================================================================================================================== ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WinVerDetect_GetVersion ; Description ...: Detects detailed Windows version information from a live or offline Windows installation path. ; Supports both running systems (live) and mounted/extracted images (offline). For live systems, requires admin privileges. ; Returns an array with version details or a specific index if requested. Uses registry for precise info, falls back to file versions. ; Syntax ........: _WinVerDetect_GetVersion([$sWindowsPath = @WindowsDir[, $iReturn = -1]]) ; Parameters ....: $sWindowsPath - String: Path to Windows directory (default: @WindowsDir for live system) ; $iReturn - Integer: Index of array element to return (default: -1 for full array) ; Return values .: Success - If $iReturn = -1: Array[10] with version info as per $WINVER_* enums ; | If $iReturn >= 0: String value from the specified array index ; Failure - Sets @error to one of $WINVER_ERROR_* codes, returns empty array/string ; Author ........: Dao Van Trong - TRONG.PRO ; Modified ......: Enhanced documentation and error handling ; Remarks .......: - For offline detection without admin: Falls back to file-based inference (less accurate). ; | - Builds and UBR are integers as strings for consistency. ; | - IsInsider detection checks for Insider Preview rings. ; Related .......: _RegReadMulti, __WinVerDetect_LiveVersion, __WinVerDetect_OfflineVersion, __WinVerDetect_FromFiles ; Example .......: #include "Windows Version Detector v5.au3" ; Local $aInfo = _WinVerDetect_GetVersion() ; If Not @error Then ConsoleWrite("OS: " & $aInfo[$WINVER_PRODUCTNAME] & @CRLF) ; =============================================================================================================================== Func _WinVerDetect_GetVersion($sWindowsPath = @WindowsDir, $iReturn = -1) ; Initialize result array with defaults (empty strings and False for boolean) Local $aResult[10] = ["", "", "", "", "", "", "", "", "", False] ; Normalize the input path to handle long paths and ensure consistency Local $sPath = __WinVerDetect_NormalizePath($sWindowsPath) ; Validate if the path points to a valid Windows installation If Not __WinVerDetect_IsValidWindowsPath($sPath) Then Return SetError($WINVER_ERROR_INVALID_PATH, 0, ($iReturn = -1) ? $aResult : $aResult[$iReturn]) EndIf ; Determine if this is a live (running) system or offline installation $aResult[$WINVER_STATE] = __WinVerDetect_IsSystemLive($sPath) ? "Live" : "Offline" ; Process based on live/offline status If $aResult[$WINVER_STATE] = "Live" Then ; For live systems, require admin privileges If Not IsAdmin() Then Return SetError($WINVER_ERROR_NO_ADMIN, 0, ($iReturn = -1) ? $aResult : $aResult[$iReturn]) EndIf ; Read from live registry $aResult = __WinVerDetect_LiveVersion($sPath) Else ; For offline, attempt registry hive load if admin, else fallback to files If IsAdmin() Then $aResult = __WinVerDetect_OfflineVersion($sPath) Else $aResult = __WinVerDetect_FromFiles($sPath) EndIf EndIf ; Propagate errors from internal functions If @error Then Return SetError(@error, @extended, ($iReturn = -1) ? $aResult : $aResult[$iReturn]) EndIf ; Fill in any missing information using the version databases $aResult = __WinVerDetect_FillMissingInfo($aResult) ; Return full array or specific index Return ($iReturn = -1) ? $aResult : $aResult[$iReturn] EndFunc ;==>_WinVerDetect_GetVersion ; #FUNCTION# ==================================================================================================================== ; Name ..........: _RegReadMulti ; Description ...: Reads multiple registry values from a single key, supporting array input, delimited strings, or single values. ; Handles errors gracefully, returning defaults for missing values. Useful for batch registry reads in version detection. ; Syntax ........: _RegReadMulti($sKey, $vFields[, $sDefault = ""[, $sSplitChar = "|"[, $sJoinChar = "|"[, $bReturnArray = False]]]]) ; Parameters ....: $sKey - String: Registry key path (e.g., "HKLM\SOFTWARE\...") ; $vFields - Variant: Array of value names, delimited string (e.g., "Value1|Value2"), or single string ; $sDefault - String: Default value if read fails (default: "") ; $sSplitChar - String: Delimiter for splitting $vFields if string (default: "|") ; $sJoinChar - String: Delimiter for joining results if not returning array (default: "|") ; $bReturnArray- Boolean: True to return array, False to return joined string (default: True) ; Return values .: Success - Array if $bReturnArray=True, joined string otherwise ; Failure - Sets @error: 1=Invalid key, 2=Empty fields, 3=Parse error; @extended=Number of values processed ; Author ........: Dao Van Trong - TRONG.PRO ; Modified ......: Added comprehensive error handling and documentation ; Remarks .......: - Strips whitespace from field names. ; | - Tracks the highest error code for partial failures. ; Related .......: RegRead (built-in) ; Example .......: Local $aValues = _RegReadMulti("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion", ["ProductName", "BuildLab"], "", "|", True) ; =============================================================================================================================== Func _RegReadMulti($sKey, $vFields, $sDefault = "", $sSplitChar = "|", $sJoinChar = "|", $bReturnArray = True) Local $aNames, $iErrorCode = 0, $iExtended = 0 ; Track errors Local $aDefaultResult[1] = [$sDefault] ; Fallback for empty fields ; Parse $vFields: Handle array, delimited string, or single value If IsArray($vFields) Then If UBound($vFields) > 0 Then $aNames = $vFields ; Direct array Else $aNames = $aDefaultResult $iErrorCode = 3 ; Empty array $iExtended = 1 EndIf Else If $vFields = "" Then $aNames = $aDefaultResult $iErrorCode = 2 ; Empty string $iExtended = 1 ElseIf $sSplitChar <> "" And StringInStr($vFields, $sSplitChar) Then ; Split delimited string $aNames = StringSplit($vFields, $sSplitChar, $STR_NOCOUNT) If UBound($aNames) > 0 Then ; Strip whitespace from each name For $i = 0 To UBound($aNames) - 1 $aNames[$i] = StringStripWS($aNames[$i], $STR_STRIPLEADING + $STR_STRIPTRAILING) Next Else $aNames = $aDefaultResult $iErrorCode = 3 $iExtended = 1 EndIf Else ; Single value as array Local $aTmp[1] = [StringStripWS($vFields, $STR_STRIPLEADING + $STR_STRIPTRAILING)] $aNames = $aTmp EndIf EndIf ; Initialize result array Local $aResult[UBound($aNames)] If $sKey = "" Then ; No key: Fill with defaults For $i = 0 To UBound($aResult) - 1 $aResult[$i] = $sDefault Next If $iErrorCode = 0 Then $iErrorCode = 1 ; Invalid key $iExtended = UBound($aResult) Else ; Read each value from registry For $i = 0 To UBound($aNames) - 1 Local $sValue = RegRead($sKey, $aNames[$i]) If @error Then $sValue = $sDefault ; Track highest error $iErrorCode = (@error > $iErrorCode) ? @error : $iErrorCode $iExtended = (@extended > $iExtended) ? @extended : $iExtended EndIf $aResult[$i] = $sValue Next EndIf ; Return array or joined string Return SetError($iErrorCode, $iExtended, $bReturnArray ? $aResult : __WinVerDetect_ArrayToString($aResult, $sJoinChar)) EndFunc ;==>_RegReadMulti ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name...........: Internal Functions ; Description ...: These functions are for internal use by the UDF and should not be called directly. ; =============================================================================================================================== ; #FUNCTION# ==================================================================================================================== ; Name ..........: __WinVerDetect_GetShortName ; Description ...: Infers a short OS identifier (e.g., "WIN_10") from the full product name. Used for standardized OS classification. ; Syntax ........: __WinVerDetect_GetShortName($sProductName) ; Parameters ....: $sProductName - String: Full product name (e.g., "Windows 10", "Windows Server 2022") ; Return values .: Success - String: Short identifier (e.g., "WIN_10", "WIN_SRV") ; Failure - "UNKNOWN" if no match ; Author ........: Dao Van Trong - TRONG.PRO ; Modified ......: Added inline comments for priority matching ; Remarks .......: - Prioritizes server versions first, then client. ; | - Case-insensitive matching using StringLower. ; Related .......: _WinVerDetect_GetVersion ; =============================================================================================================================== Func __WinVerDetect_GetShortName($sProductName) Local $sLower = StringLower($sProductName) ; Convert to lowercase for case-insensitive matching ; Prioritize server versions (check for "server" keyword first) If StringInStr($sLower, "server") Then If StringInStr($sLower, "2025") Then Return "WIN_2025" ; Windows Server 2025 If StringInStr($sLower, "2022") Then Return "WIN_2022" ; Windows Server 2022 If StringInStr($sLower, "2019") Then Return "WIN_2019" ; Windows Server 2019 If StringInStr($sLower, "2016") Then Return "WIN_2016" ; Windows Server 2016 If StringInStr($sLower, "2012 r2") Then Return "WIN_2012R2" ; Windows Server 2012 R2 If StringInStr($sLower, "2012") Then Return "WIN_2012" ; Windows Server 2012 If StringInStr($sLower, "2008 r2") Then Return "WIN_2008R2" ; Windows Server 2008 R2 If StringInStr($sLower, "2008") Then Return "WIN_2008" ; Windows Server 2008 If StringInStr($sLower, "2003 r2") Then Return "WIN_2003R2" ; Windows Server 2003 R2 If StringInStr($sLower, "2003") Then Return "WIN_2003" ; Windows Server 2003 Return "WIN_SRV" ; Generic server fallback EndIf ; Client versions (check in descending order for accuracy) If StringInStr($sLower, "windows 11") Then Return "WIN_11" If StringInStr($sLower, "windows 10") Then Return "WIN_10" If StringInStr($sLower, "windows 8.1") Then Return "WIN_81" If StringInStr($sLower, "windows 8") Then Return "WIN_8" If StringInStr($sLower, "windows 7") Then Return "WIN_7" If StringInStr($sLower, "vista") Then Return "WIN_VISTA" If StringInStr($sLower, "xp") Then Return "WIN_XP" If StringInStr($sLower, "2000") Then Return "WIN_2000" If StringInStr($sLower, "nt 4.0") Then Return "WIN_NT4" If StringInStr($sLower, "nt 3.51") Then Return "WIN_NT351" If StringInStr($sLower, "nt 3.5") Then Return "WIN_NT35" If StringInStr($sLower, "nt 3.1") Then Return "WIN_NT31" Return "UNKNOWN" ; No match found EndFunc ;==>__WinVerDetect_GetShortName ; #FUNCTION# ==================================================================================================================== ; Name ..........: __WinVerDetect_LiveVersion ; Description ...: Retrieves version info from the live system's registry. Requires admin privileges. ; Syntax ........: __WinVerDetect_LiveVersion($sPath) ; Parameters ....: $sPath - String: Path to Windows directory (must be live system) ; Return values .: Success - Array[10] with populated version fields ; Failure - Calls __WinVerDetect_FromFiles as fallback; logs error ; Author ........: Dao Van Trong - TRONG.PRO ; Modified ......: Integrated error logging and fallback ; Remarks .......: - Uses _RegReadMulti for efficient batch reading. ; | - Sets EditionType via inference if needed. ; Related .......: _RegReadMulti, __WinVerDetect_IsInsiderPreview, __WinVerDetect_FromFiles ; =============================================================================================================================== Func __WinVerDetect_LiveVersion($sPath) ; Initialize result array for live system Local $aResult[10] = ["Live", "", "", "", "", "", "", "", "", False] ; Registry key for version info Local $sKey = "HKLM\" & $REG_KEY_VERSION ; Read multiple values: ProductName, CurrentBuildNumber, DisplayVersion, UBR, EditionID Local $aRegValues = _RegReadMulti($sKey, "ProductName|CurrentBuildNumber|DisplayVersion|UBR|EditionID", "", "|", "|", True) ; Check if read succeeded (array of 5 elements) If Not @error And IsArray($aRegValues) And UBound($aRegValues) = 5 Then ; Populate result from registry values $aResult[$WINVER_PRODUCTNAME] = $aRegValues[0] ; ProductName $aResult[$WINVER_BUILD] = $aRegValues[1] ; Build $aResult[$WINVER_DISPLAYVERSION] = $aRegValues[2] ; DisplayVersion $aResult[$WINVER_UBR] = $aRegValues[3] ; UBR $aResult[$WINVER_EDITIONID] = $aRegValues[4] ; EditionID ; Infer EditionType from ProductName or EditionID $aResult[$WINVER_EDITIONTYPE] = __WinVerDetect_InferEditionType($aRegValues[0], $aRegValues[4]) ; Check for Insider Preview $aResult[$WINVER_ISINSIDER] = __WinVerDetect_IsInsiderPreview() Return $aResult Else ; Log error details for debugging __WinVerDetect_LogError("Registry read failed in __WinVerDetect_LiveVersion: Error=" & @error & ", Extended=" & @extended & ", aRegValues=" & (IsArray($aRegValues) ? __WinVerDetect_ArrayToString($aRegValues) : $aRegValues)) ; Fallback to file-based detection Return __WinVerDetect_FromFiles($sPath) EndIf EndFunc ;==>__WinVerDetect_LiveVersion ; #FUNCTION# ==================================================================================================================== ; Name ..........: __WinVerDetect_OfflineVersion ; Description ...: Loads offline registry hive and reads version info. Requires admin privileges and SeBackupPrivilege. ; Syntax ........: __WinVerDetect_OfflineVersion($sPath) ; Parameters ....: $sPath - String: Path to offline Windows directory ; Return values .: Success - Array[10] with populated version fields ; Failure - Falls back to __WinVerDetect_FromFiles; unloads hive on exit ; Author ........: Dao Van Trong - TRONG.PRO ; Modified ......: Added hive unloading and Insider check for offline ; Remarks .......: - Uses temporary key for hive loading to avoid conflicts. ; | - Ensures hive is unloaded after reading to free resources. ; Related .......: __WinVerDetect_LoadOfflineHive, __WinVerDetect_UnloadOfflineHive, __WinVerDetect_IsOfflineInsiderPreview ; =============================================================================================================================== Func __WinVerDetect_OfflineVersion($sPath) ; Initialize result array for offline system Local $aResult[10] = ["Offline", "", "", "", "", "", "", "", "", False] ; Path to SOFTWARE hive Local $sHiveFile = $sPath & $HIVE_SOFTWARE ; Check if hive file exists If Not FileExists($sHiveFile) Then Return __WinVerDetect_FromFiles($sPath) EndIf ; Generate unique temporary key for hive loading Local $sTempKey = __WinVerDetect_GenerateUniqueKey() ; Load the hive (requires backup privilege) If Not __WinVerDetect_LoadOfflineHive($sHiveFile, $sTempKey) Then Return __WinVerDetect_FromFiles($sPath) EndIf ; Read from loaded hive Local $sKey = "HKLM\" & $sTempKey & "\" & $REG_KEY_VERSION Local $aRegValues = _RegReadMulti($sKey, "ProductName|CurrentBuildNumber|DisplayVersion|UBR|EditionID", "", "|", "|", True) ; Populate result (assume success; errors handled in _RegReadMulti) $aResult[$WINVER_PRODUCTNAME] = $aRegValues[0] ; ProductName $aResult[$WINVER_BUILD] = $aRegValues[1] ; Build $aResult[$WINVER_DISPLAYVERSION] = $aRegValues[2] ; DisplayVersion $aResult[$WINVER_UBR] = $aRegValues[3] ; UBR $aResult[$WINVER_EDITIONID] = $aRegValues[4] ; EditionID ; Infer EditionType $aResult[$WINVER_EDITIONTYPE] = __WinVerDetect_InferEditionType($aRegValues[0], $aRegValues[4]) ; Check for offline Insider $aResult[$WINVER_ISINSIDER] = __WinVerDetect_IsOfflineInsiderPreview($sPath) ; Unload the hive to clean up __WinVerDetect_UnloadOfflineHive($sTempKey) Return $aResult EndFunc ;==>__WinVerDetect_OfflineVersion ; #FUNCTION# ==================================================================================================================== ; Name ..........: __WinVerDetect_FromFiles ; Description ...: Fallback detection using file versions (kernel32.dll or ntdll.dll) and edition-specific files. No admin required. ; Syntax ........: __WinVerDetect_FromFiles($sPath) ; Parameters ....: $sPath - String: Path to Windows directory ; Return values .: Success - Array[10] with build, UBR, and inferred product/edition ; Failure - Sets @error=3 if no build found ; Author ........: Dao Van Trong - TRONG.PRO ; Modified ......: Enhanced edition detection logic ; Remarks .......: - Extracts build and UBR from file version info (format: Major.Minor.Build.UBR). ; | - Infers edition by presence of specific files (e.g., ServerManager.exe for Server). ; Related .......: FileGetVersion (built-in) ; =============================================================================================================================== Func __WinVerDetect_FromFiles($sPath) ; Initialize result array for offline/file-based detection Local $aResult[10] = ["Offline", "", "", "", "", "", "", "", "", False] ; Key system files for build detection Local $aSystemFiles[2] = [$sPath & "\System32\kernel32.dll", $sPath & "\System32\ntdll.dll"] ; Try each file for version info For $sFile In $aSystemFiles If FileExists($sFile) Then Local $sFileVersion = FileGetVersion($sFile) If $sFileVersion <> "" Then Local $aVersionParts = StringSplit($sFileVersion, ".") If $aVersionParts[0] >= 4 Then ; File version format: Major.Minor.Build.UBR (e.g., 10.0.19045.4567) $aResult[$WINVER_BUILD] = $aVersionParts[3] ; Build (last but one) $aResult[$WINVER_UBR] = $aVersionParts[4] ; UBR (private build) $aResult[$WINVER_DISPLAYVERSION] = "" ; To be inferred later ExitLoop ; Success, stop checking EndIf EndIf EndIf Next ; Error if no build found If $aResult[$WINVER_BUILD] = "" Then Return SetError($WINVER_ERROR_FILE_ACCESS, 0, $aResult) EndIf ; Infer product and edition based on edition-specific files If FileExists($sPath & "\System32\ServerManager.exe") Then ; Server edition $aResult[$WINVER_PRODUCTNAME] = "Windows Server" $aResult[$WINVER_EDITIONID] = "Server" $aResult[$WINVER_EDITIONTYPE] = "Server" ElseIf FileExists($sPath & "\System32\ProfSvc.dll") Then ; Professional edition $aResult[$WINVER_PRODUCTNAME] = "Windows Professional" $aResult[$WINVER_EDITIONID] = "Professional" $aResult[$WINVER_EDITIONTYPE] = "Professional" Else ; Default to Home $aResult[$WINVER_PRODUCTNAME] = "Windows Home" $aResult[$WINVER_EDITIONID] = "Home" $aResult[$WINVER_EDITIONTYPE] = "Home" EndIf Return $aResult EndFunc ;==>__WinVerDetect_FromFiles ; #FUNCTION# ==================================================================================================================== ; Name ..........: __WinVerDetect_FillMissingInfo ; Description ...: Populates missing fields in the result array using the static version databases or inference functions. ; Syntax ........: __WinVerDetect_FillMissingInfo(ByRef $aResult) ; Parameters ....: $aResult - Array: Reference to the result array[10] to fill ; Return values .: Modified $aResult with filled fields; Sets @error=5 if invalid build ; Author ........: Dao Van Trong - TRONG.PRO ; Modified ......: Prioritized DB lookup before inference ; Remarks .......: - Uses exact DB first, then range DB. ; | - Only overrides empty fields to preserve registry data. ; Related .......: __WinVerDetect_GetVersionFromDB, __WinVerDetect_InferDisplayVersion ; =============================================================================================================================== Func __WinVerDetect_FillMissingInfo(ByRef $aResult) ; Parse build and UBR as integers for comparison Local $iBuild = Int($aResult[$WINVER_BUILD]) Local $iUBR = Int($aResult[$WINVER_UBR]) If $iBuild < 1 Then Return SetError($WINVER_ERROR_INVALID_BUILD, 0, $aResult) EndIf ; Attempt to get full info from databases Local $aVersionInfo = __WinVerDetect_GetVersionFromDB($iBuild, $iUBR) If IsArray($aVersionInfo) Then ; Use DB info if available, but only fill empty fields If $aResult[$WINVER_SHORTNAME] = "" Then $aResult[$WINVER_SHORTNAME] = $aVersionInfo[1] ; ShortOS If $aResult[$WINVER_PRODUCTNAME] = "" Then $aResult[$WINVER_PRODUCTNAME] = $aVersionInfo[2] ; ProductName If $aResult[$WINVER_FULLNAME] = "" Then $aResult[$WINVER_FULLNAME] = $aVersionInfo[3] ; VersionFullName If $aResult[$WINVER_DISPLAYVERSION] = "" Then $aResult[$WINVER_DISPLAYVERSION] = $aVersionInfo[6] ; DisplayVersion ; Only set edition if not already from registry If $aResult[$WINVER_EDITIONID] = "" Then $aResult[$WINVER_EDITIONID] = $aVersionInfo[7] If $aResult[$WINVER_EDITIONTYPE] = "" Then $aResult[$WINVER_EDITIONTYPE] = $aVersionInfo[8] Else ; Fallback to inference functions for missing fields If $aResult[$WINVER_SHORTNAME] = "" Then $aResult[$WINVER_SHORTNAME] = __WinVerDetect_GetShortName($aResult[$WINVER_PRODUCTNAME]) If $aResult[$WINVER_PRODUCTNAME] = "" Then $aResult[$WINVER_PRODUCTNAME] = "Windows" ; Default If $aResult[$WINVER_FULLNAME] = "" Then $aResult[$WINVER_FULLNAME] = __WinVerDetect_GetVersionNameByBuild($iBuild, $aResult[$WINVER_DISPLAYVERSION], $aResult[$WINVER_PRODUCTNAME], $iUBR) If $aResult[$WINVER_DISPLAYVERSION] = "" Then $aResult[$WINVER_DISPLAYVERSION] = __WinVerDetect_InferDisplayVersion($iBuild) If $aResult[$WINVER_EDITIONID] = "" Then $aResult[$WINVER_EDITIONID] = __WinVerDetect_InferEditionType($aResult[$WINVER_PRODUCTNAME], "") If $aResult[$WINVER_EDITIONTYPE] = "" Then $aResult[$WINVER_EDITIONTYPE] = __WinVerDetect_InferEditionType($aResult[$WINVER_PRODUCTNAME], $aResult[$WINVER_EDITIONID]) EndIf Return $aResult EndFunc ;==>__WinVerDetect_FillMissingInfo ; #FUNCTION# ==================================================================================================================== ; Name ..........: __WinVerDetect_GetVersionFromDB ; Description ...: Looks up version info in exact and range databases based on build and UBR. ; Syntax ........: __WinVerDetect_GetVersionFromDB($iBuild[, $iUBR = 0]) ; Parameters ....: $iBuild - Integer: Major build number ; $iUBR - Integer: Update Build Revision (optional) ; Return values .: Success - Array[10] with version details ; Failure - 0 (no match) ; Author ........: Dao Van Trong - TRONG.PRO ; Modified ......: Structured array return for consistency ; Remarks .......: - Exact DB checked first for precise matches (including UBR). ; | - Range DB for broader inference (ignores UBR). ; Related .......: __WinVerDetect_InitExactWindowsVersionDB, __WinVerDetect_InitWindowsVersionDB ; =============================================================================================================================== Func __WinVerDetect_GetVersionFromDB($iBuild, $iUBR = 0) ; Check exact build database first (precise matches) For $i = 0 To UBound($_g_aWinVerExactDB) - 1 ; Match build and UBR (UBR=-1 means any) If $iBuild = $_g_aWinVerExactDB[$i][4] And ($iUBR = $_g_aWinVerExactDB[$i][5] Or $_g_aWinVerExactDB[$i][5] = -1) Then ; Construct result array Local $aResult[10] $aResult[0] = "" ; State (not used here) $aResult[1] = __WinVerDetect_GetShortName($_g_aWinVerExactDB[$i][0]) ; ShortOS $aResult[2] = $_g_aWinVerExactDB[$i][0] ; ProductName ; Full name with version, build, and codename if available $aResult[3] = $_g_aWinVerExactDB[$i][0] & " Version " & $_g_aWinVerExactDB[$i][3] & " (Build " & $iBuild & ($iUBR > 0 ? "." & $iUBR : "") & ")" & ($_g_aWinVerExactDB[$i][2] <> "" ? " (" & $_g_aWinVerExactDB[$i][2] & ")" : "") $aResult[4] = String($iBuild) ; Build as string $aResult[5] = String($iUBR) ; UBR as string $aResult[6] = $_g_aWinVerExactDB[$i][3] ; DisplayVersion $aResult[7] = $_g_aWinVerExactDB[$i][0] ; EditionID fallback to product $aResult[8] = $_g_aWinVerExactDB[$i][0] ; EditionType fallback $aResult[9] = False ; Not Insider (DB is for stable releases) Return $aResult EndIf Next ; Fallback to range database (build range match) For $i = 0 To UBound($_g_aWinVerRangeDB) - 1 ; Check if build falls in range (MaxBuild=-1 means up to current) If $iBuild >= $_g_aWinVerRangeDB[$i][0] And ($iBuild <= $_g_aWinVerRangeDB[$i][1] Or $_g_aWinVerRangeDB[$i][1] = -1) Then Local $aResult[10] $aResult[0] = "" ; State $aResult[1] = __WinVerDetect_GetShortName($_g_aWinVerRangeDB[$i][2]) ; ShortOS $aResult[2] = $_g_aWinVerRangeDB[$i][2] ; ProductName ; Full name with inferred display version $aResult[3] = $_g_aWinVerRangeDB[$i][2] & " Version " & __WinVerDetect_InferDisplayVersion($iBuild) & " (Build " & $iBuild & ($iUBR > 0 ? "." & $iUBR : "") & ")" $aResult[4] = String($iBuild) $aResult[5] = String($iUBR) $aResult[6] = __WinVerDetect_InferDisplayVersion($iBuild) ; DisplayVersion $aResult[7] = $_g_aWinVerRangeDB[$i][2] ; EditionID fallback $aResult[8] = $_g_aWinVerRangeDB[$i][2] ; EditionType fallback $aResult[9] = False Return $aResult EndIf Next Return 0 ; No match EndFunc ;==>__WinVerDetect_GetVersionFromDB ; #FUNCTION# ==================================================================================================================== ; Name ..........: __WinVerDetect_InitExactWindowsVersionDB ; Description ...: Initializes the exact version database with historical and current Windows builds. Called at compile time. ; Syntax ........: __WinVerDetect_InitExactWindowsVersionDB() ; Parameters ....: None ; Return values .: 2D Array: [57][6] with [ProductName, Codename, ReleaseDate, DisplayVersion, Build, UBR] ; Author ........: Dao Van Trong - TRONG.PRO ; Modified ......: Updated entries for Windows 11 24H2 and Server 2025; added comments ; Remarks .......: - UBR = -1 means any UBR for that build. ; | - Covers Windows 1.0 to Windows Server 2025. ; | - Duplicate entries for SP/service packs where applicable. ; Related .......: __WinVerDetect_GetVersionFromDB ; =============================================================================================================================== Func __WinVerDetect_InitExactWindowsVersionDB() ; Define 2D array structure: [ProductName, Codename, ReleaseDate, Version, DisplayVersion, Build, UBR] Local $aDB[53][7] ; Source data entries (historical to modern) Local $aEntries[53][7] = [ _ ["Windows 95", "Chicago", "August 1995", "4.0", "4.0", 950, -1], _ ["Windows 98", "Memphis", "June 1998", "4.1", "4.1", 1998, -1], _ ["Windows 98", "Memphis", "May 1999", "4.1", "SE", 2222, -1], _ ["Windows Me", "Millennium", "September 2000", "4.9", "4.9", 3000, -1], _ ["Windows NT 3.1", "Razzle", "July 1993", "3.1", "3.1", 528, -1], _ ["Windows NT 3.5", "Daytona", "September 1994", "3.5", "3.5", 807, -1], _ ["Windows NT 3.51", "Daytona", "May 1995", "3.51", "3.51", 1057, -1], _ ["Windows NT 4.0", "Cairo", "August 1996", "4.0", "4.0", 1381, -1], _ ["Windows 2000", "NT 5.0", "February 2000", "5.0", "5.0", 2195, -1], _ ["Windows XP", "Whistler", "October 2001", "5.1", "5.1", 2600, 0], _ ["Windows XP", "Whistler", "September 9, 2002", "5.1", "SP1", 2600, 1106], _ ["Windows XP", "Whistler", "August 25, 2004", "5.1", "SP2", 2600, 2180], _ ["Windows XP", "Whistler", "April 21, 2008", "5.1", "SP3", 2600, 5512], _ ["Windows Server 2003", "Whistler Server", "April 2003", "5.2", "5.2", 3790, 0], _ ["Windows Server 2003", "Whistler Server R2", "December 2005", "5.2", "R2", 3790, 3959], _ ["Windows Vista", "Longhorn", "January 2007", "6.0", "6.0", 6000, 0], _ ["Windows Vista", "Longhorn", "January 2007", "6.0", "SP2", 6002, 18005], _ ["Windows Server 2008", "Longhorn Server", "February 2008", "6.0", "6.0", 6001, 0], _ ["Windows 7", "Blackcomb", "October 2009", "6.1", "6.1", 7600, 0], _ ["Windows 7", "Blackcomb", "February 22, 2011", "6.1", "SP1", 7601, 17514], _ ["Windows Server 2008", "Windows 7 Server", "October 2009", "6.1", "R2", 7601, 0], _ ["Windows 8", "Metro", "October 2012", "6.2", "6.2", 9200, 0], _ ["Windows Server 2012", "Windows Server 8", "September 2012", "6.2", "6.2", 9200, 0], _ ["Windows 8.1", "Blue", "October 2013", "6.3", "6.3", 9600, 0], _ ["Windows 8.1", "Blue", "April 8, 2014", "6.3", "Update 1", 9600, 17031], _ ["Windows Server 2012", "Windows Server Blue", "October 2013", "6.3", "R2", 9600, 0], _ ["Windows 10", "Threshold 1", "July 29, 2015", "10.0", "1507", 10240, 16384], _ ["Windows 10", "Threshold 2", "November 12, 2015", "10.0", "1511", 10586, 17], _ ["Windows 10", "Redstone 1", "August 2, 2016", "10.0", "1607", 14393, 10], _ ["Windows 10", "Redstone 2", "April 11, 2017", "10.0", "1703", 15063, 14], _ ["Windows 10", "Redstone 3", "October 17, 2017", "10.0", "1709", 16299, 19], _ ["Windows 10", "Redstone 4", "April 30, 2018", "10.0", "1803", 17134, 1], _ ["Windows 10", "Redstone 5", "October 2, 2018", "10.0", "1809", 17763, 1], _ ["Windows 10", "19H1", "May 21, 2019", "10.0", "1903", 18362, 30], _ ["Windows 10", "19H2", "November 12, 2019", "10.0", "1909", 18363, 418], _ ["Windows 10", "20H1", "May 27, 2020", "10.0", "2004", 19041, 264], _ ["Windows 10", "20H2", "October 20, 2020", "10.0", "20H2", 19042, 508], _ ["Windows 10", "21H1", "May 18, 2021", "10.0", "21H1", 19043, 928], _ ["Windows 10", "21H2", "November 16, 2021", "10.0", "21H2", 19044, 1288], _ ["Windows 10", "22H2", "August 9, 2022", "10.0", "22H2", 19045, 2006], _ ["Windows 11", "Sun Valley", "October 5, 2021", "10.0", "21H2", 22000, 194], _ ["Windows 11", "Sun Valley 2", "May 24, 2022", "10.0", "22H2", 22621, 1], _ ["Windows 11", "Sun Valley 3", "September 20, 2022", "10.0", "23H2", 22631, 2428], _ ["Windows 11", "Sun Valley 4", "September 26, 2023", "10.0", "23H2", 22641, 1], _ ["Windows 11", "Sun Valley 5", "June 26, 2024", "10.0", "24H2", 22651, 1], _ ["Windows Server 2008", "Longhorn Server", "February 2008", "6.0", "6.0", 6001, 0], _ ["Windows Server 2008", "Windows 7 Server", "October 2009", "6.1", "R2", 7601, 0], _ ["Windows Server 2012", "Windows Server 8", "September 2012", "6.2", "6.2", 9200, 0], _ ["Windows Server 2012", "Windows Server Blue", "October 2013", "6.3", "R2", 9600, 0], _ ["Windows Server 2016", "Windows Server vNext", "October 2016", "10.0", "1607", 14393, 0], _ ["Windows Server 2019", "Windows Server vNext", "October 2018", "10.0", "1809", 17763, 0], _ ["Windows Server 2022", "Windows Server vNext", "August 2021", "10.0", "21H2", 20348, 169], _ ["Windows Server 2025", "Windows Server vNext", "November 2024", "10.0", "24H2", 26100, 1] _ ] ; Copy entries to DB array For $i = 0 To UBound($aEntries) - 1 For $j = 0 To 6 $aDB[$i][$j] = $aEntries[$i][$j] Next Next Return $aDB EndFunc ;==>__WinVerDetect_InitExactWindowsVersionDB ; #FUNCTION# ==================================================================================================================== ; Name ..........: __WinVerDetect_InitWindowsVersionDB ; Description ...: Initializes the range-based version database for broad version inference. Called at compile time. ; Syntax ........: __WinVerDetect_InitWindowsVersionDB() ; Parameters ....: None ; Return values .: 2D Array: [22][3] with [MinBuild, MaxBuild, ProductName] ; Author ........: Dao Van Trong - TRONG.PRO ; Modified ......: Extended ranges for Windows 11 and Server 2025 ; Remarks .......: - MaxBuild = -1 indicates open-ended range (future builds). ; | - Used when exact DB fails. ; Related .......: __WinVerDetect_GetVersionFromDB ; =============================================================================================================================== Func __WinVerDetect_InitWindowsVersionDB() ; Define 2D array structure: [MinBuild, MaxBuild, ProductName] Local $aDB[19][3] ; Source data entries (ranges for inference) Local $aEntries[19][3] = [ _ [511, 528, "Windows NT 3.1"], _ [807, 807, "Windows NT 3.5"], _ [950, 950, "Windows 95"], _ [1057, 1057, "Windows NT 3.51"], _ [1381, 1381, "Windows NT 4.0"], _ [1998, 2222, "Windows 98"], _ [2195, 2195, "Windows 2000"], _ [2600, 2600, "Windows XP"], _ [3000, 3000, "Windows Me"], _ [3790, 3790, "Windows Server 2003"], _ [6000, 6001, "Windows Vista"], _ [7600, 7601, "Windows 7"], _ [9200, 9200, "Windows 8"], _ [9600, 9600, "Windows 8.1"], _ [10240, 19045, "Windows 10"], _ [22000, 22651, "Windows 11"], _ [20348, 20348, "Windows Server 2022"], _ [26100, 26100, "Windows Server 2025"] _ ] ; Copy entries to DB array For $i = 0 To UBound($aEntries) - 1 For $j = 0 To 2 $aDB[$i][$j] = $aEntries[$i][$j] Next Next Return $aDB EndFunc ;==>__WinVerDetect_InitWindowsVersionDB Func __WinVerDetect_InitEditionMap() Dim $l_aEditionMap[20][3] Local $iIndex = 0 $l_aEditionMap[$iIndex][0] = "corecountryspecific" $l_aEditionMap[$iIndex][1] = "" $l_aEditionMap[$iIndex][2] = "Home China" $iIndex += 1 $l_aEditionMap[$iIndex][0] = "professionalcountryspecific" $l_aEditionMap[$iIndex][1] = "" $l_aEditionMap[$iIndex][2] = "Pro China" $iIndex += 1 $l_aEditionMap[$iIndex][0] = "coren" $l_aEditionMap[$iIndex][1] = "" $l_aEditionMap[$iIndex][2] = "Home N" $iIndex += 1 $l_aEditionMap[$iIndex][0] = "professionaln" $l_aEditionMap[$iIndex][1] = "" $l_aEditionMap[$iIndex][2] = "Pro N" $iIndex += 1 $l_aEditionMap[$iIndex][0] = "corekn" $l_aEditionMap[$iIndex][1] = "" $l_aEditionMap[$iIndex][2] = "Home KN" $iIndex += 1 $l_aEditionMap[$iIndex][0] = "professionalkn" $l_aEditionMap[$iIndex][1] = "" $l_aEditionMap[$iIndex][2] = "Pro KN" $iIndex += 1 $l_aEditionMap[$iIndex][0] = "enterprises" $l_aEditionMap[$iIndex][1] = "" $l_aEditionMap[$iIndex][2] = "Enterprise LTSC" $iIndex += 1 $l_aEditionMap[$iIndex][0] = "iotenterprise" $l_aEditionMap[$iIndex][1] = "" $l_aEditionMap[$iIndex][2] = "IoT Enterprise" $iIndex += 1 $l_aEditionMap[$iIndex][0] = "professional" $l_aEditionMap[$iIndex][1] = "" $l_aEditionMap[$iIndex][2] = "Pro" $iIndex += 1 $l_aEditionMap[$iIndex][0] = "education" $l_aEditionMap[$iIndex][1] = "" $l_aEditionMap[$iIndex][2] = "Education" $iIndex += 1 $l_aEditionMap[$iIndex][0] = "serverstandard" $l_aEditionMap[$iIndex][1] = "" $l_aEditionMap[$iIndex][2] = "Server Standard" $iIndex += 1 $l_aEditionMap[$iIndex][0] = "serverdatacenter" $l_aEditionMap[$iIndex][1] = "" $l_aEditionMap[$iIndex][2] = "Server Datacenter" $iIndex += 1 $l_aEditionMap[$iIndex][0] = "enterpriseg" $l_aEditionMap[$iIndex][1] = "" $l_aEditionMap[$iIndex][2] = "Enterprise G" $iIndex += 1 $l_aEditionMap[$iIndex][0] = "enterprise" $l_aEditionMap[$iIndex][1] = "" $l_aEditionMap[$iIndex][2] = "Enterprise" $iIndex += 1 ReDim $l_aEditionMap[$iIndex][3] Return $l_aEditionMap EndFunc ;==>__WinVerDetect_InitEditionMap ; #FUNCTION# ==================================================================================================================== ; Name ..........: __WinVerDetect_GetVersionNameByBuild ; Description ...: Constructs a full version name string based on build, using DB or inference. Used as fallback. ; Syntax ........: __WinVerDetect_GetVersionNameByBuild($iBuild, $sDisplayVersion, $sProductName[, $iUBR = 0]) ; Parameters ....: $iBuild - Integer: Build number ; $sDisplayVersion- String: Known display version (fallback to inference) ; $sProductName - String: Known product name ; $iUBR - Integer: UBR (optional) ; Return values .: String: Full version name (e.g., "Windows 10 Version 22H2 (Build 19045)") ; Author ........: Dao Van Trong - TRONG.PRO ; Modified ......: Added server-specific formatting (no build in name for servers) ; Related .......: __WinVerDetect_GetVersionFromDB, __WinVerDetect_GetFallbackVersionName ; =============================================================================================================================== Func __WinVerDetect_GetVersionNameByBuild($iBuild, $sDisplayVersion, $sProductName, $iUBR = 0) Local $bIsServer = (StringInStr($sProductName, "Server") > 0) ; Check if server edition ; ==== Check exact DB ==== For $i = 0 To UBound($_g_aWinVerExactDB) - 1 Local $dbProduct = $_g_aWinVerExactDB[$i][0] Local $dbCodename = $_g_aWinVerExactDB[$i][1] Local $dbDate = $_g_aWinVerExactDB[$i][2] Local $dbVersion = $_g_aWinVerExactDB[$i][3] Local $dbDispVer = $_g_aWinVerExactDB[$i][4] Local $dbBuild = $_g_aWinVerExactDB[$i][5] Local $dbUBR = $_g_aWinVerExactDB[$i][6] If $iBuild = $dbBuild And ($iUBR = $dbUBR Or $dbUBR = -1) Then ; Ưu tiên ProductName đầu vào, fallback DB Local $sTemplate = $sProductName <> "" ? $sProductName : $dbProduct ; --- Thêm DisplayVersion/Version --- If $dbDispVer <> "" Then ; Nếu ProductName đã chứa rồi thì bỏ qua If StringInStr($sTemplate, $dbDispVer) = 0 Then ; Nếu DisplayVersion = Version và là số → "Version X" If $dbDispVer = $dbVersion And StringIsDigit(StringReplace($dbDispVer, ".", "")) Then $sTemplate &= " Version " & $dbVersion Else $sTemplate &= " " & $dbDispVer EndIf EndIf ElseIf $dbVersion <> "" Then If StringInStr($sTemplate, $dbVersion) = 0 Then $sTemplate &= " Version " & $dbVersion EndIf EndIf ; --- Build --- Local $sBuild = "(Build " & $iBuild & ($iUBR > 0 ? "." & $iUBR : "") & ")" $sTemplate &= " " & $sBuild ; --- Date --- If $dbDate <> "" Then $sTemplate &= " (" & $dbDate & ")" ; --- Codename --- If $dbCodename <> "" Then $sTemplate &= " (" & $dbCodename & ")" Return $sTemplate EndIf Next ; ==== Fallback to range DB ==== For $i = 0 To UBound($_g_aWinVerRangeDB) - 1 If $iBuild >= $_g_aWinVerRangeDB[$i][0] And ($iBuild <= $_g_aWinVerRangeDB[$i][1] Or $_g_aWinVerRangeDB[$i][1] = -1) Then Local $sTemplate = $sProductName <> "" ? $sProductName : $_g_aWinVerRangeDB[$i][2] If StringInStr($sTemplate, "Future") Then $sTemplate = $bIsServer ? "Windows Server" : "Windows" EndIf ; Ưu tiên DisplayVersion đầu vào, fallback infer Local $sDisplay = $sDisplayVersion <> "" ? $sDisplayVersion : __WinVerDetect_InferDisplayVersion($iBuild) If $sDisplay <> "" And StringInStr($sTemplate, $sDisplay) = 0 Then $sTemplate &= " " & $sDisplay EndIf $sTemplate &= " (Build " & $iBuild & ($iUBR > 0 ? "." & $iUBR : "") & ")" Return $sTemplate EndIf Next ; ==== Ultimate fallback ==== Return __WinVerDetect_GetFallbackVersionName($iBuild, $sDisplayVersion, $bIsServer) EndFunc ;==>__WinVerDetect_GetVersionNameByBuild ; #FUNCTION# ==================================================================================================================== ; Name ..........: __WinVerDetect_InferEditionType ; Description ...: Infers edition type (e.g., "Professional") from ProductName or EditionID. ; Syntax ........: __WinVerDetect_InferEditionType($sProductName, $sEditionID) ; Parameters ....: $sProductName - String: Full product name ; $sEditionID - String: Registry EditionID (takes precedence) ; Return values .: String: Inferred edition type ; Author ........: Dao Van Trong - TRONG.PRO ; Modified ......: Added EnterpriseS handling ; Remarks .......: - Prioritizes EditionID if provided. ; | - Case-insensitive keyword matching. ; Related .......: _WinVerDetect_GetVersion ; =============================================================================================================================== Func __WinVerDetect_InferEditionType($sProductName, $sEditionID = '') Local $sLowerID = StringLower($sEditionID) If $sLowerID <> '' Then For $i = 0 To UBound($g_aEditionMap) - 1 If StringInStr($sLowerID, $g_aEditionMap[$i][0]) > 0 Then Return $g_aEditionMap[$i][2] EndIf Next EndIf Local $sLower = StringLower($sProductName) If StringInStr($sLower, "server") Then If StringInStr($sLower, "2022") Or StringInStr($sLower, "2025") Then If StringInStr($sLower, "azure") Then Return "Server Datacenter: Azure Edition" If StringInStr($sLower, "datacenter") Then Return "Server Datacenter" If StringInStr($sLower, "standard") Then Return "Server Standard" If StringInStr($sLower, "essentials") Then Return "Server Essentials" Return "Server" EndIf If StringInStr($sLower, "2019") Then If StringInStr($sLower, "essentials") Then Return "Server Essentials" If StringInStr($sLower, "datacenter") Then Return "Server Datacenter" If StringInStr($sLower, "standard") Then Return "Server Standard" Return "Server 2019" EndIf If StringInStr($sLower, "2016") Then If StringInStr($sLower, "essentials") Then Return "Server Essentials" If StringInStr($sLower, "datacenter") Then Return "Server Datacenter" If StringInStr($sLower, "standard") Then Return "Server Standard" If StringInStr($sLower, "foundation") Then Return "Server Foundation" Return "Server 2016" EndIf If StringInStr($sLower, "essentials") Then Return "Server Essentials" If StringInStr($sLower, "datacenter") Then Return "Server Datacenter" If StringInStr($sLower, "standard") Then Return "Server Standard" Return "Server" EndIf If StringInStr($sLower, "windows 11") Then If StringInStr($sLower, "mixed reality") Then Return "Mixed Reality" If StringInStr($sLower, "iot enterprise") Then Return "IoT Enterprise" If StringInStr($sLower, "pro education") Then Return "Pro Education" If StringInStr($sLower, "pro for workstations") Then Return "Pro for Workstations" If StringInStr($sLower, "enterprise") Then Return "Enterprise" If StringInStr($sLower, "education") Then Return "Education" If StringInStr($sLower, "professional") Or StringInStr($sLower, "pro") Then Return "Pro" If StringInStr($sLower, "home") Then Return "Home" Return "Windows 11" EndIf If StringInStr($sLower, "windows 10") Then If StringInStr($sLower, "mobile enterprise") Then Return "Mobile Enterprise" If StringInStr($sLower, "mobile") Then Return "Mobile" If StringInStr($sLower, "iot enterprise") Then Return "IoT Enterprise" If StringInStr($sLower, "iot core") Then Return "IoT Core" If StringInStr($sLower, "pro education") Then Return "Pro Education" If StringInStr($sLower, "pro for workstations") Then Return "Pro for Workstations" If StringInStr($sLower, "enterprise") Then Return "Enterprise" If StringInStr($sLower, "education") Then Return "Education" If StringInStr($sLower, "professional") Or StringInStr($sLower, "pro") Then Return "Pro" If StringInStr($sLower, "home") Then Return "Home" Return "Windows 10" EndIf If StringInStr($sLower, "windows 8.1") Or StringInStr($sLower, "8.1") Then If StringInStr($sLower, "rt") Then Return "RT" If StringInStr($sLower, "single language") Then Return "Single Language" If StringInStr($sLower, "pro") And StringInStr($sLower, "media center") Then Return "Pro with Media Center" If StringInStr($sLower, "enterprise") Then Return "Enterprise" If StringInStr($sLower, "professional") Or StringInStr($sLower, "pro") Then Return "Pro" If StringInStr($sLower, "core") Or StringInStr($sLower, "windows 8.1") Then Return "Core" Return "Windows 8.1" EndIf If StringInStr($sLower, "windows 8") Then If StringInStr($sLower, "rt") Then Return "RT" If StringInStr($sLower, "enterprise") Then Return "Enterprise" If StringInStr($sLower, "professional") Or StringInStr($sLower, "pro") Then Return "Pro" If StringInStr($sLower, "core") Or StringInStr($sLower, "windows 8") Then Return "Core" Return "Windows 8" EndIf If StringInStr($sLower, "windows 7") Or StringInStr($sLower, "7") Then If StringInStr($sLower, "starter") Then Return "Starter" If StringInStr($sLower, "home basic") Then Return "Home Basic" If StringInStr($sLower, "home premium") Then Return "Home Premium" If StringInStr($sLower, "ultimate") Then Return "Ultimate" If StringInStr($sLower, "enterprise") Then Return "Enterprise" If StringInStr($sLower, "professional") Then Return "Professional" Return "Windows 7" EndIf If StringInStr($sLower, "embedded") Then Return "Embedded" If StringInStr($sLower, "starter") Then Return "Starter" If StringInStr($sLower, "ultimate") Then Return "Ultimate" If StringInStr($sLower, "mixed reality") Then Return "Mixed Reality" If StringInStr($sLower, "iot enterprise") Then Return "IoT Enterprise" If StringInStr($sLower, "iot core") Then Return "IoT Core" If StringInStr($sLower, "iot") Then Return "IoT" If StringInStr($sLower, "mobile enterprise") Then Return "Mobile Enterprise" If StringInStr($sLower, "mobile") Then Return "Mobile" If StringInStr($sLower, "rt") Then Return "RT" If StringInStr($sLower, "pro for workstations") Then Return "Pro for Workstations" If StringInStr($sLower, "workstation") Then Return "Workstation" If StringInStr($sLower, "pro education") Then Return "Pro Education" If StringInStr($sLower, "education") Then Return "Education" If StringInStr($sLower, "enterprise") Then Return "Enterprise" If StringInStr($sLower, "professional") Or StringInStr($sLower, "pro") Then If StringInStr($sLower, "media center") Then Return "Pro with Media Center" Return "Professional" EndIf If StringInStr($sLower, "home premium") Then Return "Home Premium" If StringInStr($sLower, "home basic") Then Return "Home Basic" If StringInStr($sLower, "home") Then Return "Home" If StringInStr($sLower, "core") Then Return "Core" If StringInStr($sLower, "single language") Then Return "Single Language" If StringInStr($sLower, "millennium") Then Return "Millennium Edition" If StringInStr($sLower, "second edition") Then Return "Second Edition" If $sProductName <> "" Then Return "Standard" Return "Unknown" EndFunc ;==>__WinVerDetect_InferEditionType ; #FUNCTION# ==================================================================================================================== ; Name ..........: __WinVerDetect_InferDisplayVersion ; Description ...: Infers the display version (e.g., "22H2") from the build number using known thresholds. ; Syntax ........: __WinVerDetect_InferDisplayVersion($iBuild) ; Parameters ....: $iBuild - Integer: Build number ; Return values .: String: Display version (e.g., "22H2"); Empty string if unknown ; Author ........: Dao Van Trong - TRONG.PRO ; Modified ......: Added support for builds >=26100 (Server 2025/Win11 24H2) ; Remarks .......: - Uses descending thresholds for accurate inference. ; | - Covers from Windows 1.0 to future builds. ; Related .......: __WinVerDetect_FillMissingInfo ; =============================================================================================================================== Func __WinVerDetect_InferDisplayVersion($iBuild) ; Legacy NT-based If $iBuild = 9600 Then Return "6.3" If $iBuild = 9200 Then Return "6.2" If $iBuild = 7600 Or $iBuild = 7601 Then Return "6.1" If $iBuild = 6000 Or $iBuild = 6001 Then Return "6.0" If $iBuild = 3790 Then Return "5.2" If $iBuild = 2600 Then Return "5.1" If $iBuild = 2195 Then Return "5.0" If $iBuild = 1381 Then Return "4.0" If $iBuild = 1057 Then Return "3.51" If $iBuild = 807 Then Return "3.5" ; 9x/ME If $iBuild = 3000 Then Return "4.9" If $iBuild = 1998 Then Return "4.1" If $iBuild = 950 Then Return "4.0" If $iBuild = 528 Then Return "3.1" ; Modern Windows 11/Server 2025 If $iBuild >= 26100 Then Return "24H2" If $iBuild >= 22631 Then Return "23H2" If $iBuild >= 22621 Then Return "22H2" If $iBuild >= 22000 Then Return "21H2" ; Windows 10 If $iBuild >= 19045 Then Return "22H2" If $iBuild >= 19044 Then Return "21H2" If $iBuild >= 19043 Then Return "21H1" If $iBuild >= 19042 Then Return "20H2" If $iBuild >= 19041 Then Return "2004" If $iBuild >= 18363 Then Return "1909" If $iBuild >= 18362 Then Return "1903" If $iBuild >= 17134 Then Return "1803" If $iBuild >= 16299 Then Return "1709" If $iBuild >= 15063 Then Return "1703" If $iBuild >= 14393 Then Return "1607" If $iBuild >= 10586 Then Return "1511" If $iBuild >= 10240 Then Return "1507" Return "" ; Unknown build EndFunc ;==>__WinVerDetect_InferDisplayVersion ; #FUNCTION# ==================================================================================================================== ; Name ..........: __WinVerDetect_GetFallbackVersionName ; Description ...: Generates a basic fallback version name when DB lookup fails. ; Syntax ........: __WinVerDetect_GetFallbackVersionName($iBuild, $sDisplayVersion, $bIsServer) ; Parameters ....: $iBuild - Integer: Build number ; $sDisplayVersion- String: Optional display version ; $bIsServer - Boolean: True if server edition ; Return values .: String: Basic name (e.g., "Windows (Build 12345)") ; Author ........: Dao Van Trong - TRONG.PRO ; Modified ......: Simplified for server/client distinction ; Remarks .......: - Used as last resort. ; Related .......: __WinVerDetect_GetVersionNameByBuild ; =============================================================================================================================== Func __WinVerDetect_GetFallbackVersionName($iBuild, $sDisplayVersion, $bIsServer) Local $sFallback = $bIsServer ? "Windows Server" : "Windows" If $sDisplayVersion <> "" Then $sFallback &= " Version " & $sDisplayVersion EndIf If Not $bIsServer Then $sFallback &= " (Build " & $iBuild & ")" EndIf Return $sFallback EndFunc ;==>__WinVerDetect_GetFallbackVersionName ; #FUNCTION# ==================================================================================================================== ; Name ..........: __WinVerDetect_IsInsiderPreview ; Description ...: Checks live registry for Insider Preview indicators. ; Syntax ........: __WinVerDetect_IsInsiderPreview() ; Parameters ....: None ; Return values .: Boolean: True if Insider (ContentType or ReleaseType contains "Insider") ; Author ........: Dao Van Trong - TRONG.PRO ; Modified ......: Checks both ContentType and ReleaseType ; Remarks .......: - Only for live systems. ; Related .......: __WinVerDetect_IsOfflineInsiderPreview ; =============================================================================================================================== Func __WinVerDetect_IsInsiderPreview() Local $sKey = "HKLM\" & $REG_KEY_INSIDER Local $sType = RegRead($sKey, "ContentType") If @error Or $sType = "" Then $sType = RegRead($sKey, "ReleaseType") ; Fallback key EndIf Return (Not @error And StringInStr($sType, "Insider") > 0) EndFunc ;==>__WinVerDetect_IsInsiderPreview ; #FUNCTION# ==================================================================================================================== ; Name ..........: __WinVerDetect_NormalizePath ; Description ...: Normalizes a file path, handling long paths (>240 chars) with \\?\ prefix and resolving full path via API. ; Syntax ........: __WinVerDetect_NormalizePath($sPath) ; Parameters ....: $sPath - String: Input path ; Return values .: String: Normalized full path without trailing slashes ; Author ........: Dao Van Trong - TRONG.PRO ; Modified ......: Uses DllCall for GetFullPathNameW ; Remarks .......: - Ensures compatibility with long paths in Windows. ; Related .......: DllCall("kernel32.dll", "GetFullPathNameW") ; =============================================================================================================================== Func __WinVerDetect_NormalizePath($sPath) ; Add \\?\ prefix for long paths If StringLeft($sPath, 4) <> "\\?\" And StringLen($sPath) > 240 Then $sPath = "\\?\" & $sPath EndIf ; Use Windows API to get full path Local $tBuf = DllStructCreate("wchar[" & $MAX_PATH & "]") Local $aRet = DllCall("kernel32.dll", "dword", "GetFullPathNameW", "wstr", $sPath, "dword", $MAX_PATH, "ptr", DllStructGetPtr($tBuf), "ptr", 0) If @error Or $aRet[0] = 0 Then ; Fallback: Simple replace Return StringReplace($sPath, "/", "\") EndIf ; Remove trailing backslashes Return StringRegExpReplace(DllStructGetData($tBuf, 1), "\\+$", "") EndFunc ;==>__WinVerDetect_NormalizePath ; #FUNCTION# ==================================================================================================================== ; Name ..........: __WinVerDetect_IsValidWindowsPath ; Description ...: Validates if a path is a valid Windows installation by checking key directories and files. ; Syntax ........: __WinVerDetect_IsValidWindowsPath($sPath) ; Parameters ....: $sPath - String: Path to check ; Return values .: Boolean: True if valid Windows dir ; Author ........: Dao Van Trong - TRONG.PRO ; Modified ......: Added kernel32/ntdll existence check ; Remarks .......: - Requires System32, Config, and at least one core DLL. ; Related .......: FileExists (built-in) ; =============================================================================================================================== Func __WinVerDetect_IsValidWindowsPath($sPath) If Not FileExists($sPath) Then Return False EndIf ; Check essential directories If Not FileExists($sPath & "\System32") Or Not FileExists($sPath & "\System32\Config") Then Return False EndIf ; Count core files Local $iCount = 0 If FileExists($sPath & "\System32\kernel32.dll") Then $iCount += 1 If FileExists($sPath & "\System32\ntdll.dll") Then $iCount += 1 Return $iCount > 0 ; At least one core file EndFunc ;==>__WinVerDetect_IsValidWindowsPath ; #FUNCTION# ==================================================================================================================== ; Name ..........: __WinVerDetect_IsSystemLive ; Description ...: Determines if the path is a live (running) Windows system by checking file locks on key files. ; Syntax ........: __WinVerDetect_IsSystemLive($sPath) ; Parameters ....: $sPath - String: Path to check ; Return values .: Boolean: True if live (files locked by kernel) ; Author ........: Dao Van Trong - TRONG.PRO ; Modified ......: Added ntoskrnl.exe check ; Remarks .......: - Compares to @WindowsDir first for quick live check. ; | - Uses CreateFile to test locks. ; Related .......: __WinVerDetect_IsFileLocked ; =============================================================================================================================== Func __WinVerDetect_IsSystemLive($sPath) ; Quick check: If matches current Windows dir, it's live If __WinVerDetect_NormalizePath(@WindowsDir) = $sPath Then Return True EndIf ; Check locks on key files (in-use by running system) Local $aCheck[3] = [$sPath & "\System32\Config\SYSTEM", $sPath & "\System32\Config\SOFTWARE", $sPath & "\System32\ntoskrnl.exe"] For $sFile In $aCheck If __WinVerDetect_IsFileLocked($sFile) Then Return True ; Locked = in use by live system EndIf Next Return False EndFunc ;==>__WinVerDetect_IsSystemLive ; #FUNCTION# ==================================================================================================================== ; Name ..........: __WinVerDetect_IsFileLocked ; Description ...: Tests if a file is locked (in use) using CreateFile API. ; Syntax ........: __WinVerDetect_IsFileLocked($sFile) ; Parameters ....: $sFile - String: File path to test ; Return values .: Boolean: True if locked (cannot open) ; Author ........: Dao Van Trong - TRONG.PRO ; Modified ......: Uses wide char (W) for Unicode support ; Remarks .......: - INVALID_HANDLE_VALUE (-1) indicates lock. ; Related .......: DllCall("kernel32.dll", "CreateFileW") ; =============================================================================================================================== Func __WinVerDetect_IsFileLocked($sFile) If Not FileExists($sFile) Then Return False EndIf ; Attempt to open file with read share Local $h = DllCall("kernel32.dll", "handle", "CreateFileW", "wstr", $sFile, "dword", $GENERIC_READ, "dword", $FILE_SHARE_READ, "ptr", 0, "dword", $OPEN_EXISTING, "dword", 0, "handle", 0) If @error Or $h[0] = -1 Then ; -1 = INVALID_HANDLE_VALUE Return True ; Cannot open = locked EndIf ; Close handle if opened successfully DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $h[0]) Return False EndFunc ;==>__WinVerDetect_IsFileLocked ; #FUNCTION# ==================================================================================================================== ; Name ..........: __WinVerDetect_LoadOfflineHive ; Description ...: Loads an offline registry hive into HKLM using RegLoadKeyW. Requires SeBackupPrivilege. ; Syntax ........: __WinVerDetect_LoadOfflineHive($sHiveFile, $sTempKey) ; Parameters ....: $sHiveFile - String: Path to hive file (e.g., SOFTWARE) ; $sTempKey - String: Temporary subkey name under HKLM ; Return values .: Boolean: True if loaded successfully ($ERROR_SUCCESS) ; Author ........: Dao Van Trong - TRONG.PRO ; Modified ......: Integrated privilege enablement ; Remarks .......: - Enables backup privilege before loading. ; Related .......: __WinVerDetect_EnableBackupPrivilege, RegLoadKeyW ; =============================================================================================================================== Func __WinVerDetect_LoadOfflineHive($sHiveFile, $sTempKey) ; Enable required privilege If Not __WinVerDetect_EnableBackupPrivilege() Then Return False EndIf ; Load hive via API Local $aRet = DllCall("advapi32.dll", "long", "RegLoadKeyW", "handle", $HKEY_LOCAL_MACHINE, "wstr", $sTempKey, "wstr", $sHiveFile) Return (IsArray($aRet) And $aRet[0] = $ERROR_SUCCESS) EndFunc ;==>__WinVerDetect_LoadOfflineHive ; #FUNCTION# ==================================================================================================================== ; Name ..........: __WinVerDetect_UnloadOfflineHive ; Description ...: Unloads a temporarily loaded registry hive from HKLM. ; Syntax ........: __WinVerDetect_UnloadOfflineHive($sTempKey) ; Parameters ....: $sTempKey - String: Temporary subkey to unload ; Return values .: Boolean: True if unloaded successfully ; Author ........: Dao Van Trong - TRONG.PRO ; Modified ......: Uses RegUnloadKeyW for Unicode ; Remarks .......: - Always call after loading to avoid leaks. ; Related .......: RegUnloadKeyW ; =============================================================================================================================== Func __WinVerDetect_UnloadOfflineHive($sTempKey) Local $aRet = DllCall("advapi32.dll", "long", "RegUnloadKeyW", "handle", $HKEY_LOCAL_MACHINE, "wstr", $sTempKey) Return (IsArray($aRet) And $aRet[0] = $ERROR_SUCCESS) EndFunc ;==>__WinVerDetect_UnloadOfflineHive ; #FUNCTION# ==================================================================================================================== ; Name ..........: __WinVerDetect_EnableBackupPrivilege ; Description ...: Enables SeBackupPrivilege on the current process token for hive operations. ; Syntax ........: __WinVerDetect_EnableBackupPrivilege() ; Parameters ....: None ; Return values .: Boolean: True if privilege enabled ; Author ........: Dao Van Trong - TRONG.PRO ; Modified ......: Full token privilege adjustment ; Remarks .......: - Uses AdjustTokenPrivileges API. ; | - Closes token handle on exit. ; Related .......: LookupPrivilegeValueW, AdjustTokenPrivileges ; =============================================================================================================================== Func __WinVerDetect_EnableBackupPrivilege() ; Get current process handle Local $hProc = DllCall("kernel32.dll", "handle", "GetCurrentProcess")[0] ; Open process token Local $a = DllCall("advapi32.dll", "bool", "OpenProcessToken", "handle", $hProc, "dword", 0x00000020, "handle*", 0) ; TOKEN_ADJUST_PRIVILEGES If @error Or Not $a[0] Then Return False EndIf Local $hToken = $a[3] ; Token handle ; Lookup LUID for SeBackupPrivilege Local $tLUID = DllStructCreate("int64") DllCall("advapi32.dll", "bool", "LookupPrivilegeValueW", "ptr", 0, "wstr", $SE_BACKUP_PRIVILEGE, "ptr", DllStructGetPtr($tLUID)) ; Prepare privilege structure: Enabled, LUID, Attributes=SE_PRIVILEGE_ENABLED Local $tPriv = DllStructCreate("dword;int64;dword") DllStructSetData($tPriv, 1, 1) ; PrivilegeCount DllStructSetData($tPriv, 2, DllStructGetData($tLUID, 1)) ; LUID DllStructSetData($tPriv, 3, 0x00000002) ; SE_PRIVILEGE_ENABLED ; Adjust token privileges Local $aAdjust = DllCall("advapi32.dll", "bool", "AdjustTokenPrivileges", "handle", $hToken, "bool", False, "ptr", DllStructGetPtr($tPriv), "dword", 0, "ptr", 0, "ptr", 0) Local $bSuccess = (IsArray($aAdjust) And $aAdjust[0]) ; Close token DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hToken) Return $bSuccess EndFunc ;==>__WinVerDetect_EnableBackupPrivilege ; #FUNCTION# ==================================================================================================================== ; Name ..........: __WinVerDetect_GenerateUniqueKey ; Description ...: Generates a unique temporary registry key name using GUID. ; Syntax ........: __WinVerDetect_GenerateUniqueKey() ; Parameters ....: None ; Return values .: String: Unique key (e.g., "TEMP_A1B2C3D4") ; Author ........: Dao Van Trong - TRONG.PRO ; Modified ......: Uses CoCreateGuid for randomness ; Remarks .......: - Prefix "TEMP_" for identification. ; Related .......: CoCreateGuid ; =============================================================================================================================== Func __WinVerDetect_GenerateUniqueKey() ; Create GUID structure Local $tGUID = DllStructCreate("byte[16]") DllCall("ole32.dll", "int", "CoCreateGuid", "ptr", DllStructGetPtr($tGUID)) ; Convert to hex string (first 8 chars for simplicity) Local $sHex = "" For $i = 1 To 16 $sHex &= StringFormat("%02X", DllStructGetData($tGUID, 1, $i)) Next Return "TEMP_" & StringLeft($sHex, 16) EndFunc ;==>__WinVerDetect_GenerateUniqueKey ; #FUNCTION# ==================================================================================================================== ; Name ..........: __WinVerDetect_IsOfflineInsiderPreview ; Description ...: Checks offline hive for Insider Preview, similar to live but loads hive temporarily. ; Syntax ........: __WinVerDetect_IsOfflineInsiderPreview($sPath) ; Parameters ....: $sPath - String: Offline Windows path ; Return values .: Boolean: True if Insider detected ; Author ........: Dao Van Trong - TRONG.PRO ; Modified ......: Mirrors live check with hive load/unload ; Remarks .......: - Requires admin; unloads hive after check. ; Related .......: __WinVerDetect_LoadOfflineHive, __WinVerDetect_UnloadOfflineHive ; =============================================================================================================================== Func __WinVerDetect_IsOfflineInsiderPreview($sPath) Local $sHiveFile = $sPath & $HIVE_SOFTWARE If Not FileExists($sHiveFile) Then Return False EndIf Local $sTempKey = __WinVerDetect_GenerateUniqueKey() If Not __WinVerDetect_LoadOfflineHive($sHiveFile, $sTempKey) Then Return False EndIf ; Check Insider keys in loaded hive Local $sInsiderKey = "HKLM\" & $sTempKey & "\" & $REG_KEY_INSIDER Local $sType = RegRead($sInsiderKey, "ContentType") If @error Or $sType = "" Then $sType = RegRead($sInsiderKey, "ReleaseType") EndIf Local $bResult = (Not @error And StringInStr($sType, "Insider") > 0) ; Cleanup __WinVerDetect_UnloadOfflineHive($sTempKey) Return $bResult EndFunc ;==>__WinVerDetect_IsOfflineInsiderPreview ; #FUNCTION# ==================================================================================================================== ; Name ..........: __WinVerDetect_ArrayToString ; Description ...: Converts an array to a delimited string, starting from optional index. ; Syntax ........: __WinVerDetect_ArrayToString($aArray[, $sDelimiter = "|"[, $iStart = 0]]) ; Parameters ....: $aArray - Array: Input array ; $sDelimiter- String: Delimiter (default: "|") ; $iStart - Integer: Starting index (default: 0) ; Return values .: String: Joined array elements ; Author ........: Dao Van Trong - TRONG.PRO ; Modified ......: Handles empty arrays ; Remarks .......: - Similar to _ArrayToString but custom for UDF compatibility. ; Related .......: _RegReadMulti ; =============================================================================================================================== Func __WinVerDetect_ArrayToString($aArray, $sDelimiter = "|", $iStart = 0) If Not IsArray($aArray) Or UBound($aArray) <= $iStart Then Return "" EndIf Local $sResult = $aArray[$iStart] For $i = $iStart + 1 To UBound($aArray) - 1 $sResult &= $sDelimiter & $aArray[$i] Next Return $sResult EndFunc ;==>__WinVerDetect_ArrayToString ; #FUNCTION# ==================================================================================================================== ; Name ..........: __WinVerDetect_LogError ; Description ...: Logs error messages to console for debugging (internal use). ; Syntax ........: __WinVerDetect_LogError($sMsg) ; Parameters ....: $sMsg - String: Error message ; Return values .: None (outputs to console) ; Author ........: Dao Van Trong - TRONG.PRO ; Modified ......: Simple console output ; Remarks .......: - Prefix with "!" for visibility. ; Related .......: ConsoleWrite (built-in) ; =============================================================================================================================== Func __WinVerDetect_LogError($sMsg) ConsoleWrite("! " & $sMsg & @CRLF) EndFunc ;==>__WinVerDetect_LogError : TEST : #Region TEST_SUITE ; #EXAMPLE# ===================================================================================================================== ; To run the test suite, call the function: _RunTestSuite() _RunTestSuite() ; =============================================================================================================================== ;======================================================================================================= ; Function: _RunTestSuite() ; Description: Runs the comprehensive test suite for the UDF and prints the results to the console. ; Return Value: True if all tests passed, False otherwise. ;======================================================================================================= Func _RunTestSuite() Local $iPassed = 0, $iFailed = 0, $iSkipped = 0, $iTotal = 0 ; List of test functions to execute Local $aTestsToRun[] = [ _ "_TestDatabaseInitialization", _ "_TestLiveSystemDetection", _ "_TestUtilityFunctions", _ "_TestErrorHandling", _ "_TestVersionInference", _ "_TestPathValidation", _ "_TestIndividualFieldAccess", _ "_TestSpecificBuildsAndNames", _ "_TestShortNameEdgeCases", _ "_TestLiveSystemDetails", _ "_TestSpecialEditionDetection", _ ; New Test Case 10 "_TestComprehensiveVersionNames" _ ; New Test Case 11 ] $iTotal = UBound($aTestsToRun) _PrintTestResult("STARTING COMPREHENSIVE TEST SUITE", 3) ConsoleWrite("> UDF Library: Windows Version Detector" & @CRLF) ConsoleWrite("=====================================================================================" & @CRLF) For $sTestFunc In $aTestsToRun Local $aResult = Call($sTestFunc) ; Prettify the function name for display Local $sTestName = StringRegExpReplace($sTestFunc, "^_Test", "") $sTestName = StringRegExpReplace($sTestName, "([A-Z])", " $1") $sTestName = StringStripWS($sTestName, 1) _PrintTestResult($sTestName, $aResult[0], $aResult[1]) Switch $aResult[0] Case 1 ; PASSED $iPassed += 1 Case 0 ; FAILED $iFailed += 1 Case 2 ; SKIPPED $iSkipped += 1 EndSwitch Next ConsoleWrite("=====================================================================================" & @CRLF) _PrintTestResult("TEST SUITE SUMMARY", 3) ConsoleWrite("+ Passed : " & $iPassed & @CRLF) ConsoleWrite("! Failed : " & $iFailed & @CRLF) ConsoleWrite("- Skipped : " & $iSkipped & @CRLF) ConsoleWrite("> Total : " & $iTotal & @CRLF) Local $fSuccessRate = ($iTotal > 0 And $iTotal > $iSkipped) ? ($iPassed / ($iTotal - $iSkipped)) * 100 : 0 ConsoleWrite(StringFormat("> Success Rate (excluding skipped): %.1f%%", $fSuccessRate) & @CRLF & @CRLF) Return $iFailed = 0 EndFunc ;==>_RunTestSuite ;=============================================================================== ; Function: _PrintTestResult($sTestName, $iResult, $sDetails = "") ; Description: Internal helper function to print a formatted and colored test result. ; Parameters: $sTestName - The name of the test. ; $iResult - The result code: 1 (PASSED), 0 (FAILED), 2 (SKIPPED), 3 (INFO). ; $sDetails - [optional] Additional details to print. ;=============================================================================== Func _PrintTestResult($sTestName, $iResult, $sDetails = "") Local $sStatus, $sColorChar Local Const $iNameWidth = 35 ; Column width for the test name Switch $iResult Case 1 ; PASSED $sColorChar = "+ " $sStatus = "[ PASSED ] " Case 0 ; FAILED $sColorChar = "! " $sStatus = "[ FAILED ] " Case 2 ; SKIPPED $sColorChar = "- " $sStatus = "[ SKIPPED ] " Case Else ; INFO $sColorChar = "> " $sStatus = "[ INFO ] " $sDetails = $sTestName $sTestName = "" EndSwitch Local $sPaddedName = StringFormat("%-" & $iNameWidth & "s", $sTestName) ConsoleWrite($sColorChar & $sStatus & " " & $sPaddedName & $sDetails & @CRLF) EndFunc ;==>_PrintTestResult ; ------ INDIVIDUAL TEST CASE FUNCTIONS ------ ;=============================================================================== ; Test Case: _TestDatabaseInitialization ; Description: Verifies that the global database arrays are initialized correctly. ;=============================================================================== Func _TestDatabaseInitialization() Local $aReturn[2] If Not IsArray($_g_aWinVerRangeDB) Or UBound($_g_aWinVerRangeDB, 2) <> 3 Then $aReturn[0] = 0 $aReturn[1] = "RangeDB database is invalid or has wrong structure." Return $aReturn EndIf If Not IsArray($_g_aWinVerExactDB) Or UBound($_g_aWinVerExactDB, 2) <> 7 Then $aReturn[0] = 0 $aReturn[1] = "ExactDB database is invalid or has wrong structure." Return $aReturn EndIf $aReturn[0] = 1 $aReturn[1] = "" Return $aReturn EndFunc ;==>_TestDatabaseInitialization ;=============================================================================== ; Test Case: _TestLiveSystemDetection ; Description: Performs a basic check on the currently running OS. ;=============================================================================== Func _TestLiveSystemDetection() Local $aReturn[2] If Not IsAdmin() Then $aReturn[0] = 2 $aReturn[1] = "No administrator rights, skipping live system test." Return $aReturn EndIf Local $aResult = _WinVerDetect_GetVersion() If @error Then $aReturn[0] = 0 $aReturn[1] = "An error occurred during detection. Error code: " & @error Return $aReturn EndIf If Not IsArray($aResult) Or UBound($aResult) <> 10 Then $aReturn[0] = 0 $aReturn[1] = "The returned result is not a valid array." Return $aReturn EndIf If $aResult[$WINVER_STATE] <> "Live" Then $aReturn[0] = 0 $aReturn[1] = "System state was not detected as 'Live'." Return $aReturn EndIf If $aResult[$WINVER_BUILD] = "" Or Int($aResult[$WINVER_BUILD]) < 1000 Then $aReturn[0] = 0 $aReturn[1] = "Could not retrieve a valid build number (Build: " & $aResult[$WINVER_BUILD] & ")." Return $aReturn EndIf $aReturn[0] = 1 $aReturn[1] = "Current OS: " & $aResult[$WINVER_PRODUCTNAME] Return $aReturn EndFunc ;==>_TestLiveSystemDetection ;=============================================================================== ; Test Case: _TestUtilityFunctions ; Description: Tests helper functions like GetShortName and InferDisplayVersion. ;=============================================================================== Func _TestUtilityFunctions() Local $aReturn[2] Local $sShort = __WinVerDetect_GetShortName("Windows 11 Pro") If $sShort <> "WIN_11" Then $aReturn[0] = 0 $aReturn[1] = "GetShortName failed. Expected 'WIN_11', got '" & $sShort & "'." Return $aReturn EndIf Local $sDisplay = __WinVerDetect_InferDisplayVersion(22631) If $sDisplay <> "23H2" Then $aReturn[0] = 0 $aReturn[1] = "InferDisplayVersion failed. Expected '23H2', got '" & $sDisplay & "'." Return $aReturn EndIf Local $sVersionName = __WinVerDetect_GetVersionNameByBuild(19045, "22H2", "Windows 10 Enterprise") If Not StringInStr($sVersionName, "Windows 10 Enterprise") Or Not StringInStr($sVersionName, "22H2") Then $aReturn[0] = 0 $aReturn[1] = "GetVersionName failed. Result: " & $sVersionName Return $aReturn EndIf $aReturn[0] = 1 $aReturn[1] = "" Return $aReturn EndFunc ;==>_TestUtilityFunctions ;=============================================================================== ; Test Case: _TestErrorHandling ; Description: Ensures the main function correctly handles invalid inputs. ;=============================================================================== Func _TestErrorHandling() Local $aReturn[2] _WinVerDetect_GetVersion("C:\NonExistent\Path\For\Sure") If @error <> $WINVER_ERROR_INVALID_PATH Then $aReturn[0] = 0 $aReturn[1] = "Did not catch invalid path error. Error code: " & @error Return $aReturn EndIf _WinVerDetect_GetVersion("") If @error <> $WINVER_ERROR_INVALID_PATH Then $aReturn[0] = 0 $aReturn[1] = "Did not catch empty path error. Error code: " & @error Return $aReturn EndIf $aReturn[0] = 1 $aReturn[1] = "" Return $aReturn EndFunc ;==>_TestErrorHandling ;=============================================================================== ; Test Case: _TestVersionInference ; Description: Checks display version inference for specific build numbers. ;=============================================================================== Func _TestVersionInference() Local $aReturn[2] Local $aTestBuilds[3][2] = [[19041, "2004"], [22000, "21H2"], [26100, "24H2"]] For $i = 0 To UBound($aTestBuilds) - 1 Local $sInferred = __WinVerDetect_InferDisplayVersion($aTestBuilds[$i][0]) If $sInferred <> $aTestBuilds[$i][1] Then $aReturn[0] = 0 $aReturn[1] = "Inference failed for Build " & $aTestBuilds[$i][0] & ". Expected '" & $aTestBuilds[$i][1] & "', got '" & $sInferred & "'." Return $aReturn EndIf Next $aReturn[0] = 1 $aReturn[1] = "" Return $aReturn EndFunc ;==>_TestVersionInference ;=============================================================================== ; Test Case: _TestPathValidation ; Description: Tests the __WinVerDetect_IsValidWindowsPath helper function. ;=============================================================================== Func _TestPathValidation() Local $aReturn[2] If Not __WinVerDetect_IsValidWindowsPath(@WindowsDir) Then $aReturn[0] = 0 $aReturn[1] = "Failed to validate current Windows directory (" & @WindowsDir & ")." Return $aReturn EndIf If __WinVerDetect_IsValidWindowsPath(@TempDir) Then $aReturn[0] = 0 $aReturn[1] = "Incorrectly validated Temp directory (" & @TempDir & ") as a Windows path." Return $aReturn EndIf $aReturn[0] = 1 $aReturn[1] = "" Return $aReturn EndFunc ;==>_TestPathValidation ;=============================================================================== ; Test Case: _TestIndividualFieldAccess ; Description: Tests retrieving a single field using the $iReturnIndex parameter. ;=============================================================================== Func _TestIndividualFieldAccess() Local $aReturn[2] If Not IsAdmin() Then $aReturn[0] = 2 $aReturn[1] = "Admin rights required." Return $aReturn EndIf Local $sBuild = _WinVerDetect_GetVersion(@WindowsDir, $WINVER_BUILD) If @error Or $sBuild = "" Or Int($sBuild) < 1000 Then $aReturn[0] = 0 $aReturn[1] = "Failed to retrieve individual Build Number. Error: " & @error Return $aReturn EndIf Local $sProductName = _WinVerDetect_GetVersion(@WindowsDir, $WINVER_PRODUCTNAME) If @error Or $sProductName = "" Then $aReturn[0] = 0 $aReturn[1] = "Failed to retrieve individual ProductName. Error: " & @error Return $aReturn EndIf $aReturn[0] = 1 $aReturn[1] = "Build: " & $sBuild & ", Product: " & $sProductName Return $aReturn EndFunc ;==>_TestIndividualFieldAccess ;=============================================================================== ; Test Case: _TestSpecificBuildsAndNames ; Description: Tests version name generation against known data points. ;=============================================================================== Func _TestSpecificBuildsAndNames() Local $aReturn[2] ; Test Data Format: [Build, Expected Product Name, Expected Display Version] Local $aTestCases[4][3] = [ _ [19045, "Windows 10", "22H2"], _ [22000, "Windows 11", "21H2"], _ [26100, "Windows Server 2025", "24H2"], _ [20348, "Windows Server 2022", "21H2"] _ ] For $aCase In $aTestCases Local $iBuild = $aCase[0] Local $sExpectedProduct = $aCase[1] Local $sExpectedDisplay = $aCase[2] Local $sFullName = __WinVerDetect_GetVersionNameByBuild($iBuild, "", $sExpectedProduct) If Not StringInStr($sFullName, $sExpectedProduct) Or Not StringInStr($sFullName, $sExpectedDisplay) Then $aReturn[0] = 0 $aReturn[1] = StringFormat("Build %d failed. Expected '%s %s', got '%s'", $iBuild, $sExpectedProduct, $sExpectedDisplay, $sFullName) Return $aReturn EndIf Next $aReturn[0] = 1 $aReturn[1] = "" Return $aReturn EndFunc ;==>_TestSpecificBuildsAndNames ;=============================================================================== ; Test Case: _TestShortNameEdgeCases ; Description: Tests the GetShortName function with server and unknown values. ;=============================================================================== Func _TestShortNameEdgeCases() Local $aReturn[2] If __WinVerDetect_GetShortName("Windows Server 2022") <> "WIN_2022" Then $aReturn[0] = 0 $aReturn[1] = "Failed to get short name for Server 2022." Return $aReturn EndIf Local $sReturn = __WinVerDetect_GetShortName("Some Unknown OS") If $sReturn <> "UNKNOWN" Then $aReturn[0] = 0 $aReturn[1] = "Failed to return '" & $sReturn & "' for an unrecognized OS name." Return $aReturn EndIf $aReturn[0] = 1 $aReturn[1] = "" Return $aReturn EndFunc ;==>_TestShortNameEdgeCases ;=============================================================================== ; Test Case: _TestLiveSystemDetails ; Description: Displays detailed information about the live operating system. ;=============================================================================== Func _TestLiveSystemDetails() Local $aReturn[2] If Not IsAdmin() Then $aReturn[0] = 2 $aReturn[1] = "Admin rights required." Return $aReturn EndIf Local $aResult = _WinVerDetect_GetVersion() If @error Then $aReturn[0] = 0 $aReturn[1] = "Could not retrieve system details. Error: " & @error Return $aReturn EndIf Local $sDetails = @CRLF $sDetails &= "> State: " & $aResult[$WINVER_STATE] & @CRLF $sDetails &= "> Short Name: " & $aResult[$WINVER_SHORTNAME] & @CRLF $sDetails &= "> ProductName: " & $aResult[$WINVER_PRODUCTNAME] & @CRLF $sDetails &= "> Full Name: " & $aResult[$WINVER_FULLNAME] & @CRLF $sDetails &= "> Build: " & $aResult[$WINVER_BUILD] & @CRLF $sDetails &= "> UBR: " & $aResult[$WINVER_UBR] & @CRLF $sDetails &= "> DisplayVersion: " & $aResult[$WINVER_DISPLAYVERSION] & @CRLF $sDetails &= "> EditionID: " & $aResult[$WINVER_EDITIONID] & @CRLF $sDetails &= "> EditionType: " & $aResult[$WINVER_EDITIONTYPE] & @CRLF $sDetails &= "> IsInsider: " & ($aResult[$WINVER_ISINSIDER] ? "Yes" : "No") & @CRLF $aReturn[0] = 1 $aReturn[1] = $sDetails Return $aReturn EndFunc ;==>_TestLiveSystemDetails ;=============================================================================== ; Test Case: _TestSpecialEditionDetection ; Description: Tests the __WinVerDetect_InferEditionType function for special edition detection. ;=============================================================================== Func _TestSpecialEditionDetection() Local $aReturn[2] Local $iPassEdition = 0 ; Test Data Format: [ProductName, EditionID, Expected EditionType] Local $aTestCases[14][3] = [ _ ["Windows 10 Home", "CoreCountrySpecific", "Home China"], _ ["Windows 11 Home", "CoreCountrySpecific", "Home China"], _ ["Windows 10 Pro", "ProfessionalCountrySpecific", "Pro China"], _ ["Windows 10 Home N", "CoreN", "Home N"], _ ["Windows 11 Pro N", "ProfessionalN", "Pro N"], _ ["Windows 10 Home KN", "CoreKN", "Home KN"], _ ["Windows 10 Enterprise G", "EnterpriseG", "Enterprise G"], _ ["Windows 10 Enterprise LTSC", "EnterpriseS", "Enterprise LTSC"], _ ["Windows 10 IoT Enterprise", "IoTEnterprise", "IoT Enterprise"], _ ["Windows Server 2019", "ServerStandard", "Server Standard"], _ ["Windows Server 2022", "ServerDatacenter", "Server Datacenter"], _ ["Windows Server 2022", "ServerStandardCore", "Server Standard"], _ ["Windows 11 Enterprise", "Enterprise", "Enterprise"], _ ["Windows 10 Education", "Education", "Education"] _ ] ConsoleWrite("> Testing special edition detection capabilities:" & @CRLF) For $i = 0 To UBound($aTestCases) - 1 Local $sProductName = $aTestCases[$i][0] Local $sEditionID = $aTestCases[$i][1] Local $sExpected = $aTestCases[$i][2] Local $sResult = __WinVerDetect_InferEditionType($sProductName, $sEditionID) Local $sStatus = ($sResult = $sExpected) ? "+ ✓ PASS" : "! ✗ FAIL" ConsoleWrite($sStatus & " | ProductName: " & StringFormat("%-28s", $sProductName) & " | EditionID: " & StringFormat("%-27s", $sEditionID) & " | Result: " & $sResult & @CRLF) If $sResult = $sExpected Then $iPassEdition += 1 Next Local $sSummary = "Result: " & $iPassEdition & "/" & UBound($aTestCases) & " passed" If $iPassEdition = UBound($aTestCases) Then $aReturn[0] = 1 $aReturn[1] = $sSummary Else $aReturn[0] = 0 $aReturn[1] = $sSummary EndIf ConsoleWrite("> " & $sSummary & @CRLF & @CRLF) Return $aReturn EndFunc ;==>_TestSpecialEditionDetection ;=============================================================================== ; Test Case: _TestComprehensiveVersionNames ; Description: Tests __WinVerDetect_GetVersionNameByBuild with various build numbers and product names. ;=============================================================================== Func _TestComprehensiveVersionNames() Local $aReturn[2] Local $iPassVersion = 0 ; Test Data Format: [Build, DisplayVersion, ProductName, Expected Full Name] Local $aTestCases[32][4] = [ _ [528, "", "", "Windows NT 3.1 (Build 528) (July 1993) (Razzle)"], _ [807, "", "", "Windows NT 3.5 (Build 807) (September 1994) (Daytona)"], _ [1057, "", "", "Windows NT 3.51 (Build 1057) (May 1995) (Daytona)"], _ [1381, "", "", "Windows NT 4.0 (Build 1381) (August 1996) (Cairo)"], _ [1381, "", "Windows NT Server 4.0", "Windows NT Server 4.0 (Build 1381) (August 1996) (Cairo)"], _ [950, "", "", "Windows 95 Version 4.0 (Build 950) (August 1995) (Chicago)"], _ [1998, "", "", "Windows 98 Version 4.1 (Build 1998) (June 1998) (Memphis)"], _ [2222, "", "", "Windows 98 SE (Build 2222) (May 1999) (Memphis)"], _ [3000, "", "", "Windows Me Version 4.9 (Build 3000) (September 2000) (Millennium)"], _ [2195, "", "", "Windows 2000 Version 5.0 (Build 2195) (February 2000) (NT 5.0)"], _ [2195, "", "Windows 2000 Server", "Windows 2000 Server Version 5.0 (Build 2195) (February 2000) (NT 5.0)"], _ [2600, "", "", "Windows XP Version 5.1 (Build 2600) (October 2001) (Whistler)"], _ [2600, "5.1", "", "Windows XP Version 5.1 (Build 2600) (October 2001) (Whistler)"], _ [2600, "5.1", "Windows XP Professional", "Windows XP Professional Version 5.1 (Build 2600) (October 2001) (Whistler)"], _ [3790, "", "", "Windows Server 2003 Version 5.2 (Build 3790) (April 2003) (Whistler Server)"], _ [3790, "5.2", "", "Windows Server 2003 Version 5.2 (Build 3790) (April 2003) (Whistler Server)"], _ [3790, "", "Windows Server 2003", "Windows Server 2003 Version 5.2 (Build 3790) (April 2003) (Whistler Server)"], _ [6000, "", "", "Windows Vista Version 6.0 (Build 6000) (January 2007) (Longhorn)"], _ [6000, "6.0", "", "Windows Vista Version 6.0 (Build 6000) (January 2007) (Longhorn)"], _ [7600, "", "", "Windows 7 Version 6.1 (Build 7600) (October 2009) (Blackcomb)"], _ [7600, "6.1", "", "Windows 7 Version 6.1 (Build 7600) (October 2009) (Blackcomb)"], _ [9200, "", "", "Windows 8 Version 6.2 (Build 9200) (October 2012) (Metro)"], _ [9600, "", "", "Windows 8.1 Version 6.3 (Build 9600) (October 2013) (Blue)"], _ [9600, "Update1", "", "Windows 8.1 Version 6.3 (Build 9600) (October 2013) (Blue)"], _ [10240, "", "", "Windows 10 1507 (Build 10240)"], _ [10240, "1507", "Windows 10", "Windows 10 1507 (Build 10240)"], _ [19045, "", "", "Windows 10 22H2 (Build 19045)"], _ [19045, "22H2", "Windows 10", "Windows 10 22H2 (Build 19045)"], _ [22000, "", "", "Windows 11 21H2 (Build 22000)"], _ [22000, "21H2", "Windows 11", "Windows 11 21H2 (Build 22000)"], _ [20348, "", "Windows Server 2022", "Windows Server 2022 22H2 (Build 20348)"], _ [26100, "", "Windows Server 2025", "Windows Server 2025 24H2 (Build 26100)"] _ ] ConsoleWrite("> Testing comprehensive version name generation for __WinVerDetect_GetVersionNameByBuild:" & @CRLF) For $i = 0 To UBound($aTestCases) - 1 Local $iBuild = $aTestCases[$i][0] Local $sDisplayVersion = $aTestCases[$i][1] Local $sProductName = $aTestCases[$i][2] Local $sExpected = $aTestCases[$i][3] Local $sActual = __WinVerDetect_GetVersionNameByBuild($iBuild, $sDisplayVersion, $sProductName) ;~ ConsoleWrite('['&$iBuild&', "'&$sDisplayVersion&'", "'&$sProductName&'", "'&$sActual&'"], _' & @CRLF) Local $sStatus = ($sActual = $sExpected) ? "+ ✓ PASS" : "! ✗ FAIL" ConsoleWrite($sStatus & " | Build: " & StringFormat("%-6s", $iBuild) & " | DisplayVersion: " & StringFormat("%-10s", $sDisplayVersion) & " | ProductName: " & StringFormat("%-30s", $sProductName) & " | Result: " & $sActual & @CRLF) If $sActual <> $sExpected Then ConsoleWrite(" -> Expected: " & $sExpected & @CRLF) ConsoleWrite(" -> Actual: " & $sActual & @CRLF) EndIf If $sActual = $sExpected Then $iPassVersion += 1 Next Local $sSummary = "Result: " & $iPassVersion & "/" & UBound($aTestCases) & " passed" If $iPassVersion = UBound($aTestCases) Then $aReturn[0] = 1 $aReturn[1] = $sSummary Else $aReturn[0] = 0 $aReturn[1] = $sSummary EndIf ConsoleWrite("> " & $sSummary & @CRLF & @CRLF) Return $aReturn EndFunc ;==>_TestComprehensiveVersionNames #EndRegion TEST_SUITE > Result test: > [ INFO ] STARTING COMPREHENSIVE TEST SUITE > UDF Library: Windows Version Detector ===================================================================================== + [ PASSED ] Database Initialization + [ PASSED ] Live System Detection Current OS: Windows 10 Enterprise LTSC 2021 + [ PASSED ] Utility Functions + [ PASSED ] Error Handling + [ PASSED ] Version Inference + [ PASSED ] Path Validation + [ PASSED ] Individual Field Access Build: 19045, Product: Windows 10 Enterprise LTSC 2021 + [ PASSED ] Specific Builds And Names + [ PASSED ] Short Name Edge Cases + [ PASSED ] Live System Details > State: Live > Short Name: WIN_10 > ProductName: Windows 10 Enterprise LTSC 2021 > Full Name: Windows 10 Version 22H2 (Build 19045.6216) > Build: 19045 > UBR: 6216 > DisplayVersion: 22H2 > EditionID: EnterpriseS > EditionType: Enterprise LTSC > IsInsider: No > Testing special edition detection capabilities: + ✓ PASS | ProductName: Windows 10 Home | EditionID: CoreCountrySpecific | Result: Home China + ✓ PASS | ProductName: Windows 11 Home | EditionID: CoreCountrySpecific | Result: Home China + ✓ PASS | ProductName: Windows 10 Pro | EditionID: ProfessionalCountrySpecific | Result: Pro China + ✓ PASS | ProductName: Windows 10 Home N | EditionID: CoreN | Result: Home N + ✓ PASS | ProductName: Windows 11 Pro N | EditionID: ProfessionalN | Result: Pro N + ✓ PASS | ProductName: Windows 10 Home KN | EditionID: CoreKN | Result: Home KN + ✓ PASS | ProductName: Windows 10 Enterprise G | EditionID: EnterpriseG | Result: Enterprise G + ✓ PASS | ProductName: Windows 10 Enterprise LTSC | EditionID: EnterpriseS | Result: Enterprise LTSC + ✓ PASS | ProductName: Windows 10 IoT Enterprise | EditionID: IoTEnterprise | Result: IoT Enterprise + ✓ PASS | ProductName: Windows Server 2019 | EditionID: ServerStandard | Result: Server Standard + ✓ PASS | ProductName: Windows Server 2022 | EditionID: ServerDatacenter | Result: Server Datacenter + ✓ PASS | ProductName: Windows Server 2022 | EditionID: ServerStandardCore | Result: Server Standard + ✓ PASS | ProductName: Windows 11 Enterprise | EditionID: Enterprise | Result: Enterprise + ✓ PASS | ProductName: Windows 10 Education | EditionID: Education | Result: Education > Result: 14/14 passed + [ PASSED ] Special Edition Detection Result: 14/14 passed > Testing comprehensive version name generation for __WinVerDetect_GetVersionNameByBuild: + ✓ PASS | Build: 528 | DisplayVersion: | ProductName: | Result: Windows NT 3.1 (Build 528) (July 1993) (Razzle) + ✓ PASS | Build: 807 | DisplayVersion: | ProductName: | Result: Windows NT 3.5 (Build 807) (September 1994) (Daytona) + ✓ PASS | Build: 1057 | DisplayVersion: | ProductName: | Result: Windows NT 3.51 (Build 1057) (May 1995) (Daytona) + ✓ PASS | Build: 1381 | DisplayVersion: | ProductName: | Result: Windows NT 4.0 (Build 1381) (August 1996) (Cairo) + ✓ PASS | Build: 1381 | DisplayVersion: | ProductName: Windows NT Server 4.0 | Result: Windows NT Server 4.0 (Build 1381) (August 1996) (Cairo) + ✓ PASS | Build: 950 | DisplayVersion: | ProductName: | Result: Windows 95 Version 4.0 (Build 950) (August 1995) (Chicago) + ✓ PASS | Build: 1998 | DisplayVersion: | ProductName: | Result: Windows 98 Version 4.1 (Build 1998) (June 1998) (Memphis) + ✓ PASS | Build: 2222 | DisplayVersion: | ProductName: | Result: Windows 98 SE (Build 2222) (May 1999) (Memphis) + ✓ PASS | Build: 3000 | DisplayVersion: | ProductName: | Result: Windows Me Version 4.9 (Build 3000) (September 2000) (Millennium) + ✓ PASS | Build: 2195 | DisplayVersion: | ProductName: | Result: Windows 2000 Version 5.0 (Build 2195) (February 2000) (NT 5.0) + ✓ PASS | Build: 2195 | DisplayVersion: | ProductName: Windows 2000 Server | Result: Windows 2000 Server Version 5.0 (Build 2195) (February 2000) (NT 5.0) + ✓ PASS | Build: 2600 | DisplayVersion: | ProductName: | Result: Windows XP Version 5.1 (Build 2600) (October 2001) (Whistler) + ✓ PASS | Build: 2600 | DisplayVersion: 5.1 | ProductName: | Result: Windows XP Version 5.1 (Build 2600) (October 2001) (Whistler) + ✓ PASS | Build: 2600 | DisplayVersion: 5.1 | ProductName: Windows XP Professional | Result: Windows XP Professional Version 5.1 (Build 2600) (October 2001) (Whistler) + ✓ PASS | Build: 3790 | DisplayVersion: | ProductName: | Result: Windows Server 2003 Version 5.2 (Build 3790) (April 2003) (Whistler Server) + ✓ PASS | Build: 3790 | DisplayVersion: 5.2 | ProductName: | Result: Windows Server 2003 Version 5.2 (Build 3790) (April 2003) (Whistler Server) + ✓ PASS | Build: 3790 | DisplayVersion: | ProductName: Windows Server 2003 | Result: Windows Server 2003 Version 5.2 (Build 3790) (April 2003) (Whistler Server) + ✓ PASS | Build: 6000 | DisplayVersion: | ProductName: | Result: Windows Vista Version 6.0 (Build 6000) (January 2007) (Longhorn) + ✓ PASS | Build: 6000 | DisplayVersion: 6.0 | ProductName: | Result: Windows Vista Version 6.0 (Build 6000) (January 2007) (Longhorn) + ✓ PASS | Build: 7600 | DisplayVersion: | ProductName: | Result: Windows 7 Version 6.1 (Build 7600) (October 2009) (Blackcomb) + ✓ PASS | Build: 7600 | DisplayVersion: 6.1 | ProductName: | Result: Windows 7 Version 6.1 (Build 7600) (October 2009) (Blackcomb) + ✓ PASS | Build: 9200 | DisplayVersion: | ProductName: | Result: Windows 8 Version 6.2 (Build 9200) (October 2012) (Metro) + ✓ PASS | Build: 9600 | DisplayVersion: | ProductName: | Result: Windows 8.1 Version 6.3 (Build 9600) (October 2013) (Blue) + ✓ PASS | Build: 9600 | DisplayVersion: Update1 | ProductName: | Result: Windows 8.1 Version 6.3 (Build 9600) (October 2013) (Blue) + ✓ PASS | Build: 10240 | DisplayVersion: | ProductName: | Result: Windows 10 1507 (Build 10240) + ✓ PASS | Build: 10240 | DisplayVersion: 1507 | ProductName: Windows 10 | Result: Windows 10 1507 (Build 10240) + ✓ PASS | Build: 19045 | DisplayVersion: | ProductName: | Result: Windows 10 22H2 (Build 19045) + ✓ PASS | Build: 19045 | DisplayVersion: 22H2 | ProductName: Windows 10 | Result: Windows 10 22H2 (Build 19045) + ✓ PASS | Build: 22000 | DisplayVersion: | ProductName: | Result: Windows 11 21H2 (Build 22000) + ✓ PASS | Build: 22000 | DisplayVersion: 21H2 | ProductName: Windows 11 | Result: Windows 11 21H2 (Build 22000) + ✓ PASS | Build: 20348 | DisplayVersion: | ProductName: Windows Server 2022 | Result: Windows Server 2022 22H2 (Build 20348) + ✓ PASS | Build: 26100 | DisplayVersion: | ProductName: Windows Server 2025 | Result: Windows Server 2025 24H2 (Build 26100) > Result: 32/32 passed + [ PASSED ] Comprehensive Version Names Result: 32/32 passed ===================================================================================== > [ INFO ] TEST SUITE SUMMARY + Passed : 12 ! Failed : 0 - Skipped : 0 > Total : 12 > Success Rate (excluding skipped): 100.0%
×
×
  • Create New...