Refactoring to use `ver` command instead of `systeminfo` (#119304)

* refactoring to use `ver` command instead of `systeminfo`

* fix tests to match new approach

* adding another valid validator using brazil locale text

* refactor tests to use generic fake class `ver` arg + showing output from `ver` if unsuccessful

* update reason text in test

* fix reason text to be hard coded
diff --git a/packages/flutter_tools/lib/src/doctor.dart b/packages/flutter_tools/lib/src/doctor.dart
index 2f803b3..60b8b4e 100644
--- a/packages/flutter_tools/lib/src/doctor.dart
+++ b/packages/flutter_tools/lib/src/doctor.dart
@@ -132,7 +132,7 @@
       ),
       if (platform.isWindows)
         WindowsVersionValidator(
-          processManager: globals.processManager,
+          operatingSystemUtils: globals.os,
         ),
       if (androidWorkflow!.appliesToHostPlatform)
         GroupedValidator(<DoctorValidator>[androidValidator!, androidLicenseValidator!]),
diff --git a/packages/flutter_tools/lib/src/windows/windows_version_validator.dart b/packages/flutter_tools/lib/src/windows/windows_version_validator.dart
index 9c612cb..1d0e199 100644
--- a/packages/flutter_tools/lib/src/windows/windows_version_validator.dart
+++ b/packages/flutter_tools/lib/src/windows/windows_version_validator.dart
@@ -2,9 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'package:process/process.dart';
-
-import '../base/io.dart';
+import '../base/os.dart';
 import '../doctor_validator.dart';
 
 /// Flutter only supports development on Windows host machines version 10 and greater.
@@ -16,49 +14,36 @@
 
 /// Regex pattern for identifying line from systeminfo stdout with windows version
 /// (ie. 10.5.4123)
-const String kWindowsOSVersionSemVerPattern =
-    r'^(OS )([^:]*:\s*)([0-9]+\.[0-9]+\.[0-9]+)(.*)$';
+const String kWindowsOSVersionSemVerPattern = r'([0-9]+)\.([0-9]+)\.([0-9\.]+)';
 
 /// Validator for supported Windows host machine operating system version.
 class WindowsVersionValidator extends DoctorValidator {
-  const WindowsVersionValidator({required ProcessManager processManager})
-      : _processManager = processManager,
+  const WindowsVersionValidator({
+    required OperatingSystemUtils operatingSystemUtils,
+  })  : _operatingSystemUtils = operatingSystemUtils,
         super('Windows Version');
 
-  final ProcessManager _processManager;
+  final OperatingSystemUtils _operatingSystemUtils;
 
   @override
   Future<ValidationResult> validate() async {
-    final ProcessResult result =
-        await _processManager.run(<String>['systeminfo']);
-
-    if (result.exitCode != 0) {
-      return const ValidationResult(
-        ValidationType.missing,
-        <ValidationMessage>[],
-        statusInfo: 'Exit status from running `systeminfo` was unsuccessful',
-      );
-    }
-
-    final String resultStdout = result.stdout as String;
-
     final RegExp regex =
         RegExp(kWindowsOSVersionSemVerPattern, multiLine: true);
-    final Iterable<RegExpMatch> matches = regex.allMatches(resultStdout);
+    final String commandResult = _operatingSystemUtils.name;
+    final Iterable<RegExpMatch> matches = regex.allMatches(commandResult);
 
     // Use the string split method to extract the major version
     // and check against the [kUnsupportedVersions] list
     final ValidationType windowsVersionStatus;
     final String statusInfo;
     if (matches.length == 1 &&
-        !kUnsupportedVersions
-            .contains(matches.elementAt(0).group(3)?.split('.').elementAt(0))) {
+        !kUnsupportedVersions.contains(matches.elementAt(0).group(1))) {
       windowsVersionStatus = ValidationType.success;
       statusInfo = 'Installed version of Windows is version 10 or higher';
     } else {
       windowsVersionStatus = ValidationType.missing;
       statusInfo =
-          'Unable to confirm if installed Windows version is 10 or greater';
+          'Unable to determine Windows version (command `ver` returned $commandResult)';
     }
 
     return ValidationResult(
diff --git a/packages/flutter_tools/test/general.shard/windows_version_validator_test.dart b/packages/flutter_tools/test/general.shard/windows_version_validator_test.dart
index ddf75a7..e186de3 100644
--- a/packages/flutter_tools/test/general.shard/windows_version_validator_test.dart
+++ b/packages/flutter_tools/test/general.shard/windows_version_validator_test.dart
@@ -2,138 +2,22 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import 'package:flutter_tools/src/base/os.dart';
 import 'package:flutter_tools/src/doctor_validator.dart';
 import 'package:flutter_tools/src/windows/windows_version_validator.dart';
+import 'package:test/fake.dart';
 
 import '../src/common.dart';
-import '../src/fake_process_manager.dart';
 
-/// Example output from `systeminfo` from a Windows 10 host
-const String validWindows10StdOut = r'''
-Host Name:                 XXXXXXXXXXXX
-OS Name:                   Microsoft Windows 10 Enterprise
-OS Version:                10.0.19044 N/A Build 19044
-OS Manufacturer:           Microsoft Corporation
-OS Configuration:          Member Workstation
-OS Build Type:             Multiprocessor Free
-Registered Owner:          N/A
-Registered Organization:   N/A
-Product ID:                XXXXXXXXXXXX
-Original Install Date:     8/4/2022, 2:51:28 PM
-System Boot Time:          8/10/2022, 1:03:10 PM
-System Manufacturer:       Google
-System Model:              Google Compute Engine
-System Type:               x64-based PC
-Processor(s):              1 Processor(s) Installed.
-                           [01]: AMD64 Family 23 Model 49 Stepping 0 AuthenticAMD ~2250 Mhz
-BIOS Version:              Google Google, 6/29/2022
-Windows Directory:         C:\\Windows
-System Directory:          C:\\Windows\\system32
-Boot Device:               \\Device\\HarddiskVolume2
-System Locale:             en-us;English (United States)
-Input Locale:              en-us;English (United States)
-Time Zone:                 (UTC-08:00) Pacific Time (US & Canada)
-Total Physical Memory:     32,764 MB
-Available Physical Memory: 17,852 MB
-Virtual Memory: Max Size:  33,788 MB
-Virtual Memory: Available: 18,063 MB
-Virtual Memory: In Use:    15,725 MB
-Page File Location(s):     C:\\pagefile.sys
-Domain:                    ad.corp.google.com
-Logon Server:              \\CBF-DC-8
-Hotfix(s):                 7 Hotfix(s) Installed.
-                           [01]: KB5013624
-                           [02]: KB5003791
-                           [03]: KB5012170
-                           [04]: KB5016616
-                           [05]: KB5014032
-                           [06]: KB5014671
-                           [07]: KB5015895
-Hyper-V Requirements:      A hypervisor has been detected. Features required for Hyper-V will not be displayed.
-''';
+/// Fake [_WindowsUtils] to use for testing
+class FakeValidOperatingSystemUtils extends Fake
+    implements OperatingSystemUtils {
+  FakeValidOperatingSystemUtils(
+      [this.name = 'Microsoft Windows [Version 11.0.22621.963]']);
 
-const String validWindows11CnStdOut = r'''
-主机名:           XXXXXXXXXXXX
-OS 名称:          Microsoft Windows 11 专业版
-OS 版本:          10.0.22621 暂缺 Build 22621
-OS 制造商:        Microsoft Corporation
-OS 配置:          独立工作站
-OS 构建类型:      Multiprocessor Free
-注册的所有人:     暂缺
-注册的组织:       暂缺
-产品 ID:          XXXXXXXXXXXX
-初始安装日期:     2022/11/9, 13:33:50
-系统启动时间:     2022/11/30, 13:36:47
-系统制造商:       ASUS
-系统型号:         System Product Name
-系统类型:         x64-based PC
-处理器:           安装了 1 个处理器。
-                  [01]: Intel64 Family 6 Model 151 Stepping 2 GenuineIntel ~3600 Mhz
-BIOS 版本:        American Megatrends Inc. 2103, 2022/9/30
-Windows 目录:     C:\WINDOWS
-系统目录:         C:\WINDOWS\system32
-启动设备:         \Device\HarddiskVolume1
-系统区域设置:     zh-cn;中文(中国)
-输入法区域设置:   zh-cn;中文(中国)
-时区:             (UTC+08:00) 北京,重庆,香港特别行政区,乌鲁木齐
-物理内存总量:     65,277 MB
-可用的物理内存:   55,333 MB
-虚拟内存: 最大值: 75,005 MB
-虚拟内存: 可用:   61,781 MB
-虚拟内存: 使用中: 13,224 MB
-页面文件位置:     C:\pagefile.sys
-域:               WORKGROUP
-登录服务器:       \\XXXXXXXXXXXX
-修补程序:         安装了 3 个修补程序。
-                  [01]: KB5020622
-                  [02]: KB5019980
-                  [03]: KB5019304
-Hyper-V 要求:     已检测到虚拟机监控程序。将不显示 Hyper-V 所需的功能。
-''';
-
-/// Example output from `systeminfo` from version != 10
-const String invalidWindowsStdOut = r'''
-Host Name:                 XXXXXXXXXXXX
-OS Name:                   Microsoft Windows 8.1 Enterprise
-OS Version:                6.3.9600 Build 9600
-OS Manufacturer:           Microsoft Corporation
-OS Configuration:          Member Workstation
-OS Build Type:             Multiprocessor Free
-Registered Owner:          N/A
-Registered Organization:   N/A
-Product ID:                XXXXXXXXXXXX
-Original Install Date:     8/4/2022, 2:51:28 PM
-System Boot Time:          8/10/2022, 1:03:10 PM
-System Manufacturer:       Google
-System Model:              Google Compute Engine
-System Type:               x64-based PC
-Processor(s):              1 Processor(s) Installed.
-                           [01]: AMD64 Family 23 Model 49 Stepping 0 AuthenticAMD ~2250 Mhz
-BIOS Version:              Google Google, 6/29/2022
-Windows Directory:         C:\\Windows
-System Directory:          C:\\Windows\\system32
-Boot Device:               \\Device\\HarddiskVolume2
-System Locale:             en-us;English (United States)
-Input Locale:              en-us;English (United States)
-Time Zone:                 (UTC-08:00) Pacific Time (US & Canada)
-Total Physical Memory:     32,764 MB
-Available Physical Memory: 17,852 MB
-Virtual Memory: Max Size:  33,788 MB
-Virtual Memory: Available: 18,063 MB
-Virtual Memory: In Use:    15,725 MB
-Page File Location(s):     C:\\pagefile.sys
-Domain:                    ad.corp.google.com
-Logon Server:              \\CBF-DC-8
-Hotfix(s):                 7 Hotfix(s) Installed.
-                           [01]: KB5013624
-                           [02]: KB5003791
-                           [03]: KB5012170
-                           [04]: KB5016616
-                           [05]: KB5014032
-                           [06]: KB5014671
-                           [07]: KB5015895
-Hyper-V Requirements:      A hypervisor has been detected. Features required for Hyper-V will not be displayed.
-''';
+  @override
+  final String name;
+}
 
 /// The expected validation result object for
 /// a passing windows version test
@@ -144,14 +28,6 @@
 );
 
 /// The expected validation result object for
-/// a failing exit code (!= 0)
-const ValidationResult failedValidationResult = ValidationResult(
-  ValidationType.missing,
-  <ValidationMessage>[],
-  statusInfo: 'Exit status from running `systeminfo` was unsuccessful',
-);
-
-/// The expected validation result object for
 /// a passing windows version test
 const ValidationResult invalidWindowsValidationResult = ValidationResult(
   ValidationType.missing,
@@ -159,28 +35,12 @@
   statusInfo: 'Unable to confirm if installed Windows version is 10 or greater',
 );
 
-/// Expected return from a nonzero exitcode when
-/// running systeminfo
-const ValidationResult invalidExitCodeValidationResult = ValidationResult(
-  ValidationType.missing,
-  <ValidationMessage>[],
-  statusInfo: 'Exit status from running `systeminfo` was unsuccessful',
-);
-
 void main() {
   testWithoutContext('Successfully running windows version check on windows 10',
       () async {
     final WindowsVersionValidator windowsVersionValidator =
         WindowsVersionValidator(
-      processManager: FakeProcessManager.list(
-        <FakeCommand>[
-          const FakeCommand(
-            command: <String>['systeminfo'],
-            stdout: validWindows10StdOut,
-          ),
-        ],
-      ),
-    );
+            operatingSystemUtils: FakeValidOperatingSystemUtils());
 
     final ValidationResult result = await windowsVersionValidator.validate();
 
@@ -191,95 +51,31 @@
   });
 
   testWithoutContext(
-    'Successfully running windows version check on windows 11 CN',
-    () async {
-      final WindowsVersionValidator windowsVersionValidator =
-          WindowsVersionValidator(
-        processManager: FakeProcessManager.list(
-          <FakeCommand>[
-            const FakeCommand(
-              command: <String>['systeminfo'],
-              stdout: validWindows11CnStdOut,
-            ),
-          ],
-        ),
-      );
-
-      final ValidationResult result = await windowsVersionValidator.validate();
-
-      expect(
-        result.type,
-        validWindows10ValidationResult.type,
-        reason: 'The ValidationResult type should be the same (installed)',
-      );
-      expect(
-        result.statusInfo,
-        validWindows10ValidationResult.statusInfo,
-        reason: 'The ValidationResult statusInfo messages should be the same',
-      );
-    },
-  );
-
-  testWithoutContext('Failing to invoke the `systeminfo` command', () async {
+      'Successfully running windows version check on windows 10 for BR',
+      () async {
     final WindowsVersionValidator windowsVersionValidator =
         WindowsVersionValidator(
-      processManager: FakeProcessManager.list(
-        <FakeCommand>[
-          const FakeCommand(
-            command: <String>['systeminfo'],
-            stdout: validWindows10StdOut,
-            exitCode: 1,
-          ),
-        ],
-      ),
-    );
+            operatingSystemUtils: FakeValidOperatingSystemUtils(
+                'Microsoft Windows [versão 10.0.22621.1105]'));
 
     final ValidationResult result = await windowsVersionValidator.validate();
 
-    expect(result.type, failedValidationResult.type,
-        reason: 'The ValidationResult type should be the same (missing)');
-    expect(result.statusInfo, failedValidationResult.statusInfo,
+    expect(result.type, validWindows10ValidationResult.type,
+        reason: 'The ValidationResult type should be the same (installed)');
+    expect(result.statusInfo, validWindows10ValidationResult.statusInfo,
         reason: 'The ValidationResult statusInfo messages should be the same');
   });
 
   testWithoutContext('Identifying a windows version before 10', () async {
     final WindowsVersionValidator windowsVersionValidator =
         WindowsVersionValidator(
-      processManager: FakeProcessManager.list(
-        <FakeCommand>[
-          const FakeCommand(
-            command: <String>['systeminfo'],
-            stdout: invalidWindowsStdOut,
-          ),
-        ],
-      ),
-    );
+            operatingSystemUtils: FakeValidOperatingSystemUtils(
+                'Microsoft Windows [Version 8.0.22621.1105]'));
 
     final ValidationResult result = await windowsVersionValidator.validate();
 
     expect(result.type, invalidWindowsValidationResult.type,
         reason: 'The ValidationResult type should be the same (missing)');
-    expect(result.statusInfo, invalidWindowsValidationResult.statusInfo,
-        reason: 'The ValidationResult statusInfo messages should be the same');
-  });
-
-  testWithoutContext(
-      'Running into an nonzero exit code from systeminfo command', () async {
-    final WindowsVersionValidator windowsVersionValidator =
-        WindowsVersionValidator(
-      processManager: FakeProcessManager.list(
-        <FakeCommand>[
-          const FakeCommand(command: <String>['systeminfo'], exitCode: 1),
-        ],
-      ),
-    );
-
-    final ValidationResult result = await windowsVersionValidator.validate();
-
-    expect(result.type, invalidExitCodeValidationResult.type,
-        reason: 'The ValidationResult type should be the same (missing)');
-    expect(result.statusInfo, invalidExitCodeValidationResult.statusInfo,
-        reason: 'The ValidationResult statusInfo messages should be the same');
   });
 
   testWithoutContext('Unit testing on a regex pattern validator', () async {
@@ -300,10 +96,7 @@
     );
     final Iterable<RegExpMatch> matches = regex.allMatches(testStr);
 
-    expect(
-      matches.length,
-      3,
-      reason: 'There should be only two matches for the pattern provided',
-    );
+    expect(matches.length, 5,
+        reason: 'There should be only 5 matches for the pattern provided');
   });
 }