From 4570430446b1c037973efe04407668e2792f9cf0 Mon Sep 17 00:00:00 2001 From: hualxie Date: Wed, 2 Sep 2026 14:20:12 +0800 Subject: [PATCH 1/3] Add Windows build details to winml sys Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- docs/commands/sys.md | 11 ++- src/winml/modelkit/commands/sys.py | 56 +++++++++++++- tests/unit/sysinfo/test_sysinfo.py | 114 ++++++++++++++++++++++++++++- 3 files changed, 178 insertions(+), 3 deletions(-) diff --git a/docs/commands/sys.md b/docs/commands/sys.md index 5f4c917c5..ab8c96036 100644 --- a/docs/commands/sys.md +++ b/docs/commands/sys.md @@ -30,7 +30,10 @@ $ winml sys [options] ## How it works `winml sys` queries Python's `platform` and `importlib.metadata` modules to report -library versions, then probes PyTorch for CUDA availability and GPU device names. +library versions. On Windows, it also reads the native +`HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion` registry key to report the +product name, display version, build, update build revision (UBR), build branch, +and build lab. It then probes PyTorch for CUDA availability and GPU device names. Backend availability checks use the installed runtime environment, while device enumeration queries hardware directly in NPU > GPU > CPU priority order, and EP enumeration merges the WinML EP registry with ONNX Runtime's @@ -55,6 +58,12 @@ Environment Python Executable C:\...\python.exe OS Windows 11 Machine AMD64 + Product Name Windows 11 Pro + Display Version 24H2 + Current Build 26100 + UBR 4946 + Build Branch ge_release + BuildLabEx 26100.1.amd64fre.ge_release.240331-1435 ML Libraries Library Version Status diff --git a/src/winml/modelkit/commands/sys.py b/src/winml/modelkit/commands/sys.py index a1f7cdf91..4c51910df 100644 --- a/src/winml/modelkit/commands/sys.py +++ b/src/winml/modelkit/commands/sys.py @@ -114,6 +114,16 @@ def _get_python_info() -> dict[str, Any]: 0x14C: "x86", } +_WINDOWS_CURRENT_VERSION_KEY = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion" +_WINDOWS_VERSION_VALUES = { + "ProductName": "product_name", + "DisplayVersion": "display_version", + "CurrentBuild": "current_build", + "UBR": "ubr", + "BuildBranch": "build_branch", + "BuildLabEx": "build_lab_ex", +} + if sys.platform == "win32": try: @@ -173,6 +183,34 @@ def _get_windows_native_machine() -> str | None: return name +def _get_windows_version_info() -> dict[str, str | int]: + """Read detailed Windows version metadata from the native registry view.""" + if sys.platform != "win32": + return {} + + import winreg + + result: dict[str, str | int] = {} + try: + with winreg.OpenKey( + winreg.HKEY_LOCAL_MACHINE, + _WINDOWS_CURRENT_VERSION_KEY, + access=winreg.KEY_READ | winreg.KEY_WOW64_64KEY, + ) as key: + for registry_name, output_name in _WINDOWS_VERSION_VALUES.items(): + try: + value, _value_type = winreg.QueryValueEx(key, registry_name) + except OSError: + logger.debug("Windows registry value is unavailable: %s", registry_name) + continue + if isinstance(value, (str, int)): + result[output_name] = value + except OSError as exc: + logger.debug("Failed to read detailed Windows version information: %s", exc) + + return result + + def _get_platform_info() -> dict[str, Any]: """Gather OS and platform information.""" system = platform.system() @@ -181,6 +219,7 @@ def _get_platform_info() -> dict[str, Any]: # For Windows, use OS class for accurate Windows 11 detection # platform.release() may incorrectly report '10' on some Python versions + windows_version: dict[str, str | int] = {} if system == "Windows": try: os_info = OS.get() @@ -195,13 +234,16 @@ def _get_platform_info() -> dict[str, Any]: native_machine = _get_windows_native_machine() if native_machine: machine = native_machine + windows_version = _get_windows_version_info() - return { + result = { "system": system, "release": release, "machine": machine, "processor": platform.processor() or "Unknown", } + result.update(windows_version) + return result def _get_memory_info() -> dict[str, int | None]: @@ -402,6 +444,18 @@ def _output_text(info: dict[str, Any], verbose: bool = False) -> None: table.add_row("Python Executable", info["python"]["executable"]) table.add_row("OS", f"{info['platform']['system']} {info['platform']['release']}") table.add_row("Machine", info["platform"]["machine"]) + windows_rows = ( + ("Product Name", "product_name"), + ("Display Version", "display_version"), + ("Current Build", "current_build"), + ("UBR", "ubr"), + ("Build Branch", "build_branch"), + ("BuildLabEx", "build_lab_ex"), + ) + for label, key in windows_rows: + value = info["platform"].get(key) + if value is not None: + table.add_row(label, escape(str(value))) console.print("\n[bold blue]Environment[/bold blue]") console.print(table) diff --git a/tests/unit/sysinfo/test_sysinfo.py b/tests/unit/sysinfo/test_sysinfo.py index f831af027..87c7b796e 100644 --- a/tests/unit/sysinfo/test_sysinfo.py +++ b/tests/unit/sysinfo/test_sysinfo.py @@ -66,14 +66,120 @@ def test_returns_none_on_non_windows(self, monkeypatch: pytest.MonkeyPatch) -> N assert sys_mod._get_windows_native_machine() is None +class TestGetWindowsVersionInfo: + """Test detailed Windows version collection from the registry.""" + + def test_reads_available_current_version_values( + self, monkeypatch: pytest.MonkeyPatch + ) -> None: + from winml.modelkit.commands import sys as sys_mod + + values = { + "ProductName": ("Windows 11 Pro", 1), + "DisplayVersion": ("24H2", 1), + "CurrentBuild": ("26100", 1), + "UBR": (4946, 4), + "BuildBranch": ("ge_release", 1), + "BuildLabEx": ("26100.1.amd64fre.ge_release.240331-1435", 1), + } + key = MagicMock() + winreg = MagicMock() + winreg.HKEY_LOCAL_MACHINE = object() + winreg.KEY_READ = 0x20019 + winreg.KEY_WOW64_64KEY = 0x100 + winreg.OpenKey.return_value.__enter__.return_value = key + winreg.QueryValueEx.side_effect = lambda _key, name: values[name] + + monkeypatch.setattr(sys, "platform", "win32") + with patch.dict(sys.modules, {"winreg": winreg}): + result = sys_mod._get_windows_version_info() + + assert result == { + "product_name": "Windows 11 Pro", + "display_version": "24H2", + "current_build": "26100", + "ubr": 4946, + "build_branch": "ge_release", + "build_lab_ex": "26100.1.amd64fre.ge_release.240331-1435", + } + winreg.OpenKey.assert_called_once_with( + winreg.HKEY_LOCAL_MACHINE, + sys_mod._WINDOWS_CURRENT_VERSION_KEY, + access=winreg.KEY_READ | winreg.KEY_WOW64_64KEY, + ) + + def test_keeps_other_values_when_one_is_missing( + self, monkeypatch: pytest.MonkeyPatch + ) -> None: + from winml.modelkit.commands import sys as sys_mod + + winreg = MagicMock() + winreg.HKEY_LOCAL_MACHINE = object() + winreg.KEY_READ = 0x20019 + winreg.KEY_WOW64_64KEY = 0x100 + winreg.QueryValueEx.side_effect = [ + ("Windows 11 Pro", 1), + OSError("missing"), + ("26100", 1), + (4946, 4), + ("ge_release", 1), + ("build-lab", 1), + ] + + monkeypatch.setattr(sys, "platform", "win32") + with patch.dict(sys.modules, {"winreg": winreg}): + result = sys_mod._get_windows_version_info() + + assert "display_version" not in result + assert result["product_name"] == "Windows 11 Pro" + assert result["current_build"] == "26100" + + def test_returns_empty_when_registry_key_is_unavailable( + self, monkeypatch: pytest.MonkeyPatch + ) -> None: + from winml.modelkit.commands import sys as sys_mod + + winreg = MagicMock() + winreg.HKEY_LOCAL_MACHINE = object() + winreg.KEY_READ = 0x20019 + winreg.KEY_WOW64_64KEY = 0x100 + winreg.OpenKey.side_effect = OSError("access denied") + + monkeypatch.setattr(sys, "platform", "win32") + with patch.dict(sys.modules, {"winreg": winreg}): + assert sys_mod._get_windows_version_info() == {} + + def test_returns_empty_on_non_windows(self, monkeypatch: pytest.MonkeyPatch) -> None: + from winml.modelkit.commands import sys as sys_mod + + monkeypatch.setattr(sys, "platform", "linux") + + assert sys_mod._get_windows_version_info() == {} + + class TestGetPlatformInfo: """Test _get_platform_info function.""" @patch("winml.modelkit.commands.sys._get_windows_native_machine", return_value=None) + @patch( + "winml.modelkit.commands.sys._get_windows_version_info", + return_value={ + "product_name": "Windows 11 Pro", + "display_version": "24H2", + "current_build": "26100", + "ubr": 4946, + "build_branch": "ge_release", + "build_lab_ex": "build-lab", + }, + ) @patch("winml.modelkit.commands.sys.OS") @patch("winml.modelkit.commands.sys.platform") def test_windows_11_detection( - self, mock_platform: MagicMock, mock_os_class: MagicMock, _mock_native: MagicMock + self, + mock_platform: MagicMock, + mock_os_class: MagicMock, + _mock_version: MagicMock, + _mock_native: MagicMock, ) -> None: """Test Windows 11 is correctly detected.""" from winml.modelkit.commands.sys import _get_platform_info @@ -93,6 +199,12 @@ def test_windows_11_detection( assert result["system"] == "Windows" assert result["release"] == "11" # Should be corrected to 11 assert result["machine"] == "AMD64" + assert result["product_name"] == "Windows 11 Pro" + assert result["display_version"] == "24H2" + assert result["current_build"] == "26100" + assert result["ubr"] == 4946 + assert result["build_branch"] == "ge_release" + assert result["build_lab_ex"] == "build-lab" mock_os_class.get.assert_called_once() @patch("winml.modelkit.commands.sys._get_windows_native_machine", return_value=None) From 23b25136f845a778fdf193b2c1d09d63e108f92f Mon Sep 17 00:00:00 2001 From: hualxie Date: Wed, 2 Sep 2026 14:48:27 +0800 Subject: [PATCH 2/3] Fix Windows platform metadata typing Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- src/winml/modelkit/commands/sys.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/winml/modelkit/commands/sys.py b/src/winml/modelkit/commands/sys.py index 4c51910df..32587c97d 100644 --- a/src/winml/modelkit/commands/sys.py +++ b/src/winml/modelkit/commands/sys.py @@ -236,7 +236,7 @@ def _get_platform_info() -> dict[str, Any]: machine = native_machine windows_version = _get_windows_version_info() - result = { + result: dict[str, Any] = { "system": system, "release": release, "machine": machine, From 0c0a171bbd84171cf8012a9d685e62992b36ff21 Mon Sep 17 00:00:00 2001 From: hualxie Date: Wed, 2 Sep 2026 16:07:39 +0800 Subject: [PATCH 3/3] Remove unreliable Windows product name Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- docs/commands/sys.md | 5 ++--- src/winml/modelkit/commands/sys.py | 2 -- tests/unit/sysinfo/test_sysinfo.py | 6 ------ 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/docs/commands/sys.md b/docs/commands/sys.md index ab8c96036..9c6a3817f 100644 --- a/docs/commands/sys.md +++ b/docs/commands/sys.md @@ -32,8 +32,8 @@ $ winml sys [options] `winml sys` queries Python's `platform` and `importlib.metadata` modules to report library versions. On Windows, it also reads the native `HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion` registry key to report the -product name, display version, build, update build revision (UBR), build branch, -and build lab. It then probes PyTorch for CUDA availability and GPU device names. +display version, build, update build revision (UBR), build branch, and build lab. +It then probes PyTorch for CUDA availability and GPU device names. Backend availability checks use the installed runtime environment, while device enumeration queries hardware directly in NPU > GPU > CPU priority order, and EP enumeration merges the WinML EP registry with ONNX Runtime's @@ -58,7 +58,6 @@ Environment Python Executable C:\...\python.exe OS Windows 11 Machine AMD64 - Product Name Windows 11 Pro Display Version 24H2 Current Build 26100 UBR 4946 diff --git a/src/winml/modelkit/commands/sys.py b/src/winml/modelkit/commands/sys.py index 32587c97d..372cbd2d7 100644 --- a/src/winml/modelkit/commands/sys.py +++ b/src/winml/modelkit/commands/sys.py @@ -116,7 +116,6 @@ def _get_python_info() -> dict[str, Any]: _WINDOWS_CURRENT_VERSION_KEY = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion" _WINDOWS_VERSION_VALUES = { - "ProductName": "product_name", "DisplayVersion": "display_version", "CurrentBuild": "current_build", "UBR": "ubr", @@ -445,7 +444,6 @@ def _output_text(info: dict[str, Any], verbose: bool = False) -> None: table.add_row("OS", f"{info['platform']['system']} {info['platform']['release']}") table.add_row("Machine", info["platform"]["machine"]) windows_rows = ( - ("Product Name", "product_name"), ("Display Version", "display_version"), ("Current Build", "current_build"), ("UBR", "ubr"), diff --git a/tests/unit/sysinfo/test_sysinfo.py b/tests/unit/sysinfo/test_sysinfo.py index 87c7b796e..86b8af5ba 100644 --- a/tests/unit/sysinfo/test_sysinfo.py +++ b/tests/unit/sysinfo/test_sysinfo.py @@ -75,7 +75,6 @@ def test_reads_available_current_version_values( from winml.modelkit.commands import sys as sys_mod values = { - "ProductName": ("Windows 11 Pro", 1), "DisplayVersion": ("24H2", 1), "CurrentBuild": ("26100", 1), "UBR": (4946, 4), @@ -95,7 +94,6 @@ def test_reads_available_current_version_values( result = sys_mod._get_windows_version_info() assert result == { - "product_name": "Windows 11 Pro", "display_version": "24H2", "current_build": "26100", "ubr": 4946, @@ -118,7 +116,6 @@ def test_keeps_other_values_when_one_is_missing( winreg.KEY_READ = 0x20019 winreg.KEY_WOW64_64KEY = 0x100 winreg.QueryValueEx.side_effect = [ - ("Windows 11 Pro", 1), OSError("missing"), ("26100", 1), (4946, 4), @@ -131,7 +128,6 @@ def test_keeps_other_values_when_one_is_missing( result = sys_mod._get_windows_version_info() assert "display_version" not in result - assert result["product_name"] == "Windows 11 Pro" assert result["current_build"] == "26100" def test_returns_empty_when_registry_key_is_unavailable( @@ -164,7 +160,6 @@ class TestGetPlatformInfo: @patch( "winml.modelkit.commands.sys._get_windows_version_info", return_value={ - "product_name": "Windows 11 Pro", "display_version": "24H2", "current_build": "26100", "ubr": 4946, @@ -199,7 +194,6 @@ def test_windows_11_detection( assert result["system"] == "Windows" assert result["release"] == "11" # Should be corrected to 11 assert result["machine"] == "AMD64" - assert result["product_name"] == "Windows 11 Pro" assert result["display_version"] == "24H2" assert result["current_build"] == "26100" assert result["ubr"] == 4946