From 255cee2f1e0fa6ad11b8e45537212e1078c881aa Mon Sep 17 00:00:00 2001 From: Gitii Date: Fri, 27 Sep 2024 20:19:40 +0200 Subject: [PATCH 01/56] add workflows for platform tests --- .github/workflows/tests.yml | 70 ++++++++++++++++++++ Hardware.Info.Test/Hardware.Info.Test.csproj | 1 + Hardware.Info.Test/Program.cs | 60 +++++++++++++++-- Hardware.Info.Test/TestSuite.cs | 54 +++++++++++++++ 4 files changed, 180 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/tests.yml create mode 100644 Hardware.Info.Test/TestSuite.cs diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..753fdcd --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,70 @@ +name: Run Tests on all supported platforms + +on: + push: + branches: + - main + pull_request: + branches: + - main + workflow_dispatch: + +jobs: + build: + name: Build on ${{ matrix.os }} (${{ matrix.architecture }}) + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + architecture: [x64] # add arm64 when such runner are available + dotnet: ['8.x'] + fail-fast: false + env: + RUN_TIME: "${{ fromJson('{ \"ubuntu-latest\": \"linux-x64\", \"windows-latest\": \"win-x64\", \"macos-latest\": \"osx-x64\" }')[matrix.os] }}" + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Setup .NET SDK + - name: Setup .NET SDK + uses: actions/setup-dotnet@v3 + with: + dotnet-version: '${{ matrix.dotnet }}' # Adjust the version to the one required by Hardware.Info project + include-prerelease: false + + # Display installed .NET SDKs + - name: Display .NET SDK version + run: dotnet --info + + # Run with jit + - name: Run tests with jit + shell: bash + run: | + dotnet run \ + --project Hardware.Info.Test/Hardware.Info.Test.csproj \ + --configuration Release \ + -r "$RUN_TIME" \ + --verbosity quiet \ + -- \ + --enable-test-mode \ + --expected-compiler jit \ + --expected-arch ${{ matrix.architecture }} \ + --no-readline + + # Run with aot + - name: Run tests with aot + shell: bash + run: | + dotnet publish \ + Hardware.Info.Test/Hardware.Info.Test.csproj \ + --configuration Release \ + -r "$RUN_TIME" \ + -p PublishAot=true \ + --verbosity quiet + + .\Hardware.Info.Test\bin\Release\net8.0\$RUN_TIME\publish\Hardware.Info.Test \ + --enable-test-mode \ + --expected-compiler aot \ + --expected-arch ${{ matrix.architecture }} \ + --no-readline \ No newline at end of file diff --git a/Hardware.Info.Test/Hardware.Info.Test.csproj b/Hardware.Info.Test/Hardware.Info.Test.csproj index 56e8a63..cfe56c7 100644 --- a/Hardware.Info.Test/Hardware.Info.Test.csproj +++ b/Hardware.Info.Test/Hardware.Info.Test.csproj @@ -5,6 +5,7 @@ net8.0 12.0 enable + false diff --git a/Hardware.Info.Test/Program.cs b/Hardware.Info.Test/Program.cs index d574b89..fcec73a 100644 --- a/Hardware.Info.Test/Program.cs +++ b/Hardware.Info.Test/Program.cs @@ -1,18 +1,63 @@ using System; using System.Net.NetworkInformation; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace Hardware.Info.Test { class Program { - static void Main(string[] _) + static int Main(string[] args) { - Test(true); + bool testMode = TestSuite.HasFlag(args, "--enable-test-mode"); + bool noReadLine = TestSuite.HasFlag(args, "--no-readline"); + TestSuite.Compiler expectedCompiler = TestSuite.ReadOption(args, "--expected-compiler", TestSuite.Compiler.Unknown); + TestSuite.Architecture expectedArch = TestSuite.ReadOption(args, "--expected-arch", TestSuite.Architecture.Unknown); + + if (testMode) + { + var isJit = RuntimeFeature.IsDynamicCodeCompiled; + Console.WriteLine($"Process Architecture: {RuntimeInformation.ProcessArchitecture}"); + Console.WriteLine($"Operating System Architecture: {RuntimeInformation.OSArchitecture}"); + Console.WriteLine($"Compiler: {(isJit ? "JIT" : "AOT")}"); + Console.WriteLine($"Expected Compiler: {expectedCompiler}"); + Console.WriteLine($"Expected Architecture: {expectedArch}"); + + if (expectedCompiler == TestSuite.Compiler.Jit && !isJit) + { + Console.WriteLine($"Expected JIT compiler but was {expectedCompiler}"); + return 1; + } - Test(false); - } + if (expectedCompiler == TestSuite.Compiler.Aot && isJit) + { + Console.WriteLine($"Expected AOT compiler but was {expectedCompiler}"); + return 1; + } + + if (expectedArch == TestSuite.Architecture.x64 && RuntimeInformation.ProcessArchitecture != + System.Runtime.InteropServices.Architecture.X64) + { + Console.WriteLine($"Expected architecture: {expectedArch} but was {RuntimeInformation.ProcessArchitecture}"); + return 1; + } + + if (expectedArch == TestSuite.Architecture.arm64 && RuntimeInformation.ProcessArchitecture != + System.Runtime.InteropServices.Architecture.Arm64) + { + Console.WriteLine($"Expected architecture: {expectedArch} but was {RuntimeInformation.ProcessArchitecture}"); + return 1; + } + } + + Test(true, noReadLine: noReadLine); - static void Test(bool test) + Test(false, noReadLine: noReadLine); + + return 0; + } + + static void Test(bool test, bool noReadLine) { IHardwareInfo hardwareInfo = new HardwareInfo(useAsteriskInWMI: test); @@ -114,6 +159,11 @@ static void Test(bool test) foreach (var address in HardwareInfo.GetLocalIPv4Addresses()) Console.WriteLine(address); + if (!noReadLine) + { + return; + } + Console.ReadLine(); } } diff --git a/Hardware.Info.Test/TestSuite.cs b/Hardware.Info.Test/TestSuite.cs new file mode 100644 index 0000000..a348322 --- /dev/null +++ b/Hardware.Info.Test/TestSuite.cs @@ -0,0 +1,54 @@ +using System; + +namespace Hardware.Info.Test; + +class TestSuite +{ + internal enum Compiler + { + Unknown = 0, + Jit, + Aot + } + + internal enum Architecture + { + Unknown = 0, + x64, + arm64 + } + + + public static bool HasFlag(string[] args, string flagName) + { + return Array.IndexOf(args, flagName) >= 0; + } + + public static string? ReadOption(string[] args, string optionName) + { + var index = Array.IndexOf(args, optionName); + if (index < 0 | index >= args.Length) + { + return null; + } + + return args[index+1]; + } + + public static TEnum ReadOption(string[] args, string optionName, TEnum defaultValue) where TEnum : struct, System.Enum + { + var value = ReadOption(args, optionName); + if (value == null) + { + return defaultValue; + } + + var parsedValue = Enum.Parse(value, true); + if (!Enum.IsDefined(parsedValue)) + { + return defaultValue; + } + + return parsedValue; + } +} \ No newline at end of file From 39fddb3446f0289da76209fa73e2e71fd46b54a4 Mon Sep 17 00:00:00 2001 From: Gitii Date: Fri, 27 Sep 2024 21:03:23 +0200 Subject: [PATCH 02/56] handle tfm selection better --- .github/workflows/tests.yml | 5 +++++ Hardware.Info/Hardware.Info.csproj | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 753fdcd..7dde9fa 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -25,6 +25,11 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 + + - name: Install deps on linux + if: {{ matrix.os == 'ubuntu-latest' }} + shell: bash + run: apt update && apt install clang zlib1g-dev # Setup .NET SDK - name: Setup .NET SDK diff --git a/Hardware.Info/Hardware.Info.csproj b/Hardware.Info/Hardware.Info.csproj index f0333d7..1544363 100644 --- a/Hardware.Info/Hardware.Info.csproj +++ b/Hardware.Info/Hardware.Info.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + net8.0 8.0 enable From 5809db266995ac39e12a73d0a6f503eee0892327 Mon Sep 17 00:00:00 2001 From: Gitii Date: Fri, 27 Sep 2024 21:04:36 +0200 Subject: [PATCH 03/56] . --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7dde9fa..b380144 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -27,7 +27,7 @@ jobs: uses: actions/checkout@v3 - name: Install deps on linux - if: {{ matrix.os == 'ubuntu-latest' }} + if: ${{ matrix.os == 'ubuntu-latest' }} shell: bash run: apt update && apt install clang zlib1g-dev From 9078c63c9ba52209b1f5bddb7dce52345dc44c9f Mon Sep 17 00:00:00 2001 From: Gitii Date: Fri, 27 Sep 2024 21:06:00 +0200 Subject: [PATCH 04/56] . --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b380144..d916eb0 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -29,7 +29,7 @@ jobs: - name: Install deps on linux if: ${{ matrix.os == 'ubuntu-latest' }} shell: bash - run: apt update && apt install clang zlib1g-dev + run: sudo apt update && sudo apt install clang zlib1g-dev # Setup .NET SDK - name: Setup .NET SDK From 4ba2820816d97de60dda33485599d41856f53b9b Mon Sep 17 00:00:00 2001 From: Gitii Date: Fri, 27 Sep 2024 21:10:58 +0200 Subject: [PATCH 05/56] . --- .github/workflows/tests.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d916eb0..c9ce7d3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -58,7 +58,7 @@ jobs: --no-readline # Run with aot - - name: Run tests with aot + - name: Compile ahead-of-time shell: bash run: | dotnet publish \ @@ -67,7 +67,10 @@ jobs: -r "$RUN_TIME" \ -p PublishAot=true \ --verbosity quiet - + + - name: Run tests with aot + shell: bash + run: | .\Hardware.Info.Test\bin\Release\net8.0\$RUN_TIME\publish\Hardware.Info.Test \ --enable-test-mode \ --expected-compiler aot \ From 3727398acf28c479ebd808c05097173b13ef4078 Mon Sep 17 00:00:00 2001 From: Gitii Date: Fri, 27 Sep 2024 21:15:21 +0200 Subject: [PATCH 06/56] . --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c9ce7d3..e87c6bb 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -71,7 +71,7 @@ jobs: - name: Run tests with aot shell: bash run: | - .\Hardware.Info.Test\bin\Release\net8.0\$RUN_TIME\publish\Hardware.Info.Test \ + ./Hardware.Info.Test/bin/Release/net8.0/$RUN_TIME/publish/Hardware.Info.Test \ --enable-test-mode \ --expected-compiler aot \ --expected-arch ${{ matrix.architecture }} \ From f3f20f3a32ab6b22d986dde7a62f82bebf1fc46e Mon Sep 17 00:00:00 2001 From: Gitii Date: Fri, 27 Sep 2024 21:22:57 +0200 Subject: [PATCH 07/56] . --- .github/workflows/tests.yml | 9 +++++++-- Hardware.Info.Test/Program.cs | 22 +++++++++++----------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e87c6bb..0f53aee 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -51,11 +51,12 @@ jobs: --configuration Release \ -r "$RUN_TIME" \ --verbosity quiet \ + -p WarningLevel=0 \ -- \ --enable-test-mode \ --expected-compiler jit \ --expected-arch ${{ matrix.architecture }} \ - --no-readline + --no-readline | tee ./output.jit # Run with aot - name: Compile ahead-of-time @@ -75,4 +76,8 @@ jobs: --enable-test-mode \ --expected-compiler aot \ --expected-arch ${{ matrix.architecture }} \ - --no-readline \ No newline at end of file + --no-readline | tee ./output.aot + + - name: Verify that output is identical + shell: bash + run: diff ./output.jit ./output.aot \ No newline at end of file diff --git a/Hardware.Info.Test/Program.cs b/Hardware.Info.Test/Program.cs index fcec73a..a9f3557 100644 --- a/Hardware.Info.Test/Program.cs +++ b/Hardware.Info.Test/Program.cs @@ -17,35 +17,35 @@ static int Main(string[] args) if (testMode) { var isJit = RuntimeFeature.IsDynamicCodeCompiled; - Console.WriteLine($"Process Architecture: {RuntimeInformation.ProcessArchitecture}"); - Console.WriteLine($"Operating System Architecture: {RuntimeInformation.OSArchitecture}"); - Console.WriteLine($"Compiler: {(isJit ? "JIT" : "AOT")}"); - Console.WriteLine($"Expected Compiler: {expectedCompiler}"); - Console.WriteLine($"Expected Architecture: {expectedArch}"); + Console.Error.WriteLine($"Process Architecture: {RuntimeInformation.ProcessArchitecture}"); + Console.Error.WriteLine($"Operating System Architecture: {RuntimeInformation.OSArchitecture}"); + Console.Error.WriteLine($"Compiler: {(isJit ? "JIT" : "AOT")}"); + Console.Error.WriteLine($"Expected Compiler: {expectedCompiler}"); + Console.Error.WriteLine($"Expected Architecture: {expectedArch}"); if (expectedCompiler == TestSuite.Compiler.Jit && !isJit) { - Console.WriteLine($"Expected JIT compiler but was {expectedCompiler}"); + Console.Error.WriteLine($"Expected JIT compiler but was {expectedCompiler}"); return 1; } if (expectedCompiler == TestSuite.Compiler.Aot && isJit) { - Console.WriteLine($"Expected AOT compiler but was {expectedCompiler}"); + Console.Error.WriteLine($"Expected AOT compiler but was {expectedCompiler}"); return 1; } if (expectedArch == TestSuite.Architecture.x64 && RuntimeInformation.ProcessArchitecture != - System.Runtime.InteropServices.Architecture.X64) + Architecture.X64) { - Console.WriteLine($"Expected architecture: {expectedArch} but was {RuntimeInformation.ProcessArchitecture}"); + Console.Error.WriteLine($"Expected architecture: {expectedArch} but was {RuntimeInformation.ProcessArchitecture}"); return 1; } if (expectedArch == TestSuite.Architecture.arm64 && RuntimeInformation.ProcessArchitecture != - System.Runtime.InteropServices.Architecture.Arm64) + Architecture.Arm64) { - Console.WriteLine($"Expected architecture: {expectedArch} but was {RuntimeInformation.ProcessArchitecture}"); + Console.Error.WriteLine($"Expected architecture: {expectedArch} but was {RuntimeInformation.ProcessArchitecture}"); return 1; } } From 9eb6b3974573d8a6078eba7477747be846603d2a Mon Sep 17 00:00:00 2001 From: Gitii Date: Fri, 27 Sep 2024 21:31:08 +0200 Subject: [PATCH 08/56] . --- .github/workflows/tests.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0f53aee..ab89fec 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -15,7 +15,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest, windows-latest, macos-latest] + os: [ubuntu-latest, windows-latest, macos-13] architecture: [x64] # add arm64 when such runner are available dotnet: ['8.x'] fail-fast: false @@ -79,5 +79,6 @@ jobs: --no-readline | tee ./output.aot - name: Verify that output is identical + if: ${{ false }} shell: bash run: diff ./output.jit ./output.aot \ No newline at end of file From b87d4b685bd727146c70814de40fa925bcbf531e Mon Sep 17 00:00:00 2001 From: Gitii Date: Fri, 27 Sep 2024 21:33:34 +0200 Subject: [PATCH 09/56] . --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ab89fec..0ab96b6 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,7 +20,7 @@ jobs: dotnet: ['8.x'] fail-fast: false env: - RUN_TIME: "${{ fromJson('{ \"ubuntu-latest\": \"linux-x64\", \"windows-latest\": \"win-x64\", \"macos-latest\": \"osx-x64\" }')[matrix.os] }}" + RUN_TIME: "${{ fromJson('{ \"ubuntu-latest\": \"linux-x64\", \"windows-latest\": \"win-x64\", \"macos-13\": \"osx-x64\" }')[matrix.os] }}" steps: - name: Checkout repository From 45f0828bdca90eb0897fe97039804e3316c8fd91 Mon Sep 17 00:00:00 2001 From: Gitii Date: Fri, 27 Sep 2024 21:39:39 +0200 Subject: [PATCH 10/56] . --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0ab96b6..8785d3b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -24,7 +24,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install deps on linux if: ${{ matrix.os == 'ubuntu-latest' }} From 2bec2bfa832bc03f1fc28994870178d9a1bae3b3 Mon Sep 17 00:00:00 2001 From: Gitii Date: Sun, 29 Sep 2024 12:59:23 +0200 Subject: [PATCH 11/56] Split packages and add aot windows package. --- Hardware.Info.Aot.Windows/Constants.cs | 24 + .../EnumerationOptions.cs | 8 + .../Hardware.Info.Aot.Windows.csproj | 32 + .../ManagementObjectSearcher.cs | 422 +++++++++ Hardware.Info.Aot.Windows/NativeMethods.json | 8 + Hardware.Info.Aot.Windows/NativeMethods.txt | 38 + .../PlatformHardwareInfo.cs | 829 ++++++++++++++++++ Hardware.Info.Aot/Hardware.Info.Aot.csproj | 43 + Hardware.Info.Aot/HardwareInfo.cs | 346 ++++++++ .../Components/BIOS.cs | 2 +- .../Components/Battery.cs | 2 +- .../Components/CPU.cs | 2 +- .../Components/ComputerSystem.cs | 2 +- .../Components/CpuCore.cs | 2 +- .../Components/Drive.cs | 2 +- .../Components/Keyboard.cs | 2 +- .../Components/Memory.cs | 2 +- .../Components/MemoryStatus.cs | 2 +- .../Components/Monitor.cs | 2 +- .../Components/Motherboard.cs | 2 +- .../Components/Mouse.cs | 2 +- .../Components/NetworkAdapter.cs | 2 +- .../Components/OS.cs | 2 +- .../Components/Printer.cs | 2 +- .../Components/SoundDevice.cs | 2 +- .../Components/VideoController.cs | 2 +- Hardware.Info.Core/Hardware.Info.Core.csproj | 33 + .../IHardwareInfo.cs | 1 + .../IPlatformHardwareInfo.cs | 4 +- .../PlatformHardwareInfoBase.cs | 4 +- .../Hardware.Info.Linux.csproj | 22 + .../PlatformHardwareInfo.cs | 3 +- Hardware.Info.Mac/Hardware.Info.Mac.csproj | 22 + .../PlatformHardwareInfo.cs | 4 +- Hardware.Info.Test/Hardware.Info.Test.csproj | 9 +- Hardware.Info.Test/Program.cs | 6 + .../Hardware.Info.Windows.csproj | 29 + .../PlatformHardwareInfo.cs | 5 +- Hardware.Info.sln | 36 + Hardware.Info/Hardware.Info.csproj | 12 +- Hardware.Info/HardwareInfo.cs | 41 +- .../HardwareInfo.snk => HardwareInfo.snk | Bin 42 files changed, 1963 insertions(+), 52 deletions(-) create mode 100644 Hardware.Info.Aot.Windows/Constants.cs create mode 100644 Hardware.Info.Aot.Windows/EnumerationOptions.cs create mode 100644 Hardware.Info.Aot.Windows/Hardware.Info.Aot.Windows.csproj create mode 100644 Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs create mode 100644 Hardware.Info.Aot.Windows/NativeMethods.json create mode 100644 Hardware.Info.Aot.Windows/NativeMethods.txt create mode 100644 Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs create mode 100644 Hardware.Info.Aot/Hardware.Info.Aot.csproj create mode 100644 Hardware.Info.Aot/HardwareInfo.cs rename {Hardware.Info => Hardware.Info.Core}/Components/BIOS.cs (98%) rename {Hardware.Info => Hardware.Info.Core}/Components/Battery.cs (99%) rename {Hardware.Info => Hardware.Info.Core}/Components/CPU.cs (99%) rename {Hardware.Info => Hardware.Info.Core}/Components/ComputerSystem.cs (98%) rename {Hardware.Info => Hardware.Info.Core}/Components/CpuCore.cs (98%) rename {Hardware.Info => Hardware.Info.Core}/Components/Drive.cs (99%) rename {Hardware.Info => Hardware.Info.Core}/Components/Keyboard.cs (97%) rename {Hardware.Info => Hardware.Info.Core}/Components/Memory.cs (99%) rename {Hardware.Info => Hardware.Info.Core}/Components/MemoryStatus.cs (98%) rename {Hardware.Info => Hardware.Info.Core}/Components/Monitor.cs (99%) rename {Hardware.Info => Hardware.Info.Core}/Components/Motherboard.cs (97%) rename {Hardware.Info => Hardware.Info.Core}/Components/Mouse.cs (98%) rename {Hardware.Info => Hardware.Info.Core}/Components/NetworkAdapter.cs (99%) rename {Hardware.Info => Hardware.Info.Core}/Components/OS.cs (96%) rename {Hardware.Info => Hardware.Info.Core}/Components/Printer.cs (98%) rename {Hardware.Info => Hardware.Info.Core}/Components/SoundDevice.cs (98%) rename {Hardware.Info => Hardware.Info.Core}/Components/VideoController.cs (99%) create mode 100644 Hardware.Info.Core/Hardware.Info.Core.csproj rename {Hardware.Info => Hardware.Info.Core}/IHardwareInfo.cs (99%) rename Hardware.Info/IHardwareInfoRetrieval.cs => Hardware.Info.Core/IPlatformHardwareInfo.cs (91%) rename Hardware.Info/HardwareInfoBase.cs => Hardware.Info.Core/PlatformHardwareInfoBase.cs (98%) create mode 100644 Hardware.Info.Linux/Hardware.Info.Linux.csproj rename Hardware.Info/Linux/HardwareInfoRetrieval.cs => Hardware.Info.Linux/PlatformHardwareInfo.cs (99%) create mode 100644 Hardware.Info.Mac/Hardware.Info.Mac.csproj rename Hardware.Info/Mac/HardwareInfoRetrieval.cs => Hardware.Info.Mac/PlatformHardwareInfo.cs (99%) create mode 100644 Hardware.Info.Windows/Hardware.Info.Windows.csproj rename Hardware.Info/Windows/HardwareInfoRetrieval.cs => Hardware.Info.Windows/PlatformHardwareInfo.cs (99%) rename Hardware.Info/HardwareInfo.snk => HardwareInfo.snk (100%) diff --git a/Hardware.Info.Aot.Windows/Constants.cs b/Hardware.Info.Aot.Windows/Constants.cs new file mode 100644 index 0000000..fd4b829 --- /dev/null +++ b/Hardware.Info.Aot.Windows/Constants.cs @@ -0,0 +1,24 @@ +using System.Runtime.InteropServices; +using Windows.Win32; + +namespace Hardware.Info.Aot.Windows +{ + class Constants + { + public static readonly Guid CLSID_WbemLocator = new Guid( + 0x4590f811, 0x1d3a, 0x11d0, 0x89, 0x1f, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24 + ); + + public static readonly Guid IID_IWbemLocator = new Guid( + 0xdc12a687, 0x737f, 0x11cf, 0x88, 0x4d, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24 + ); + + public const int WBEM_INFINITE = unchecked((int)0xFFFFFFFF); + public const int RPC_C_AUTHN_WINNT = 10; + public const int RPC_C_AUTHZ_NONE = 0; + + public const int WBEM_E_NOT_FOUND = unchecked((int)0x80041002); + + public static readonly SafeHandle NullSafeHandle = new SysFreeStringSafeHandle(IntPtr.Zero, false); + } +} diff --git a/Hardware.Info.Aot.Windows/EnumerationOptions.cs b/Hardware.Info.Aot.Windows/EnumerationOptions.cs new file mode 100644 index 0000000..792bebb --- /dev/null +++ b/Hardware.Info.Aot.Windows/EnumerationOptions.cs @@ -0,0 +1,8 @@ +namespace Hardware.Info.Aot.Windows; + +struct EnumerationOptions +{ + public bool ReturnImmediately { get; set; } + public bool Rewindable { get; set; } + public int Timeout { get; set; } +} \ No newline at end of file diff --git a/Hardware.Info.Aot.Windows/Hardware.Info.Aot.Windows.csproj b/Hardware.Info.Aot.Windows/Hardware.Info.Aot.Windows.csproj new file mode 100644 index 0000000..ae81e92 --- /dev/null +++ b/Hardware.Info.Aot.Windows/Hardware.Info.Aot.Windows.csproj @@ -0,0 +1,32 @@ + + + + net8.0 + enable + enable + + true + true + true + true + + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + <_Parameter1>Hardware.Info.Aot + + + + diff --git a/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs b/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs new file mode 100644 index 0000000..f74e9a2 --- /dev/null +++ b/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs @@ -0,0 +1,422 @@ +using System.Buffers; +using System.Runtime.InteropServices; +using Windows.Win32; +using Windows.Win32.Foundation; +using Windows.Win32.System.Com; +using Windows.Win32.System.Variant; +using Windows.Win32.System.Wmi; +using static Hardware.Info.Aot.Windows.Constants; + +namespace Hardware.Info.Aot.Windows +{ + delegate HRESULT ExtractValueDelegate(in VARIANT variant, out T value); + delegate HRESULT ExtractArrayValueDelegate(in VARIANT variant, Span value, out uint length); + + + class ManagementObjectSearcher : IDisposable + { + private readonly int _timeout; + private SafeHandle _managementScope; + private SafeHandle _queryString; + private readonly SafeHandle _strQueryLanguage; + + public ManagementObjectSearcher(string managementScope, string queryString, int timeout) + { + _timeout = timeout; + + _managementScope = PInvoke.SysAllocString(managementScope); + _queryString = PInvoke.SysAllocString(queryString); + + _strQueryLanguage = PInvoke.SysAllocString("WQL"); + } + + public unsafe WmiSearch Get() + { + // Obtain the initial locator to WMI + IWbemLocator* pLoc; + var hr = PInvoke.CoCreateInstance( + CLSID_WbemLocator, + (IUnknown*)0, + CLSCTX.CLSCTX_INPROC_SERVER, + out pLoc + ); + + if (hr.Failed) + { + PInvoke.CoUninitialize(); + hr.ThrowOnFailure(); + return WmiSearch.Null; + } + + // Connect to WMI through the IWbemLocator::ConnectServer method + IWbemServices* pSvc; + + hr = pLoc->ConnectServer( + _managementScope, + new SysFreeStringSafeHandle(0), // User name + new SysFreeStringSafeHandle(0), // Password + new SysFreeStringSafeHandle(0), // Locale + 0, // Security flags + new SysFreeStringSafeHandle(0), // Authority + (IWbemContext*)0, // Context + &pSvc // IWbemServices proxy + ); + + if (hr.Failed) + { + pLoc->Release(); + PInvoke.CoUninitialize(); + return WmiSearch.Null; + } + + // Set security levels on the proxy + hr = PInvoke.CoSetProxyBlanket( + (IUnknown*)pSvc, + RPC_C_AUTHN_WINNT, + RPC_C_AUTHZ_NONE, + new PWSTR((char*)0), + RPC_C_AUTHN_LEVEL.RPC_C_AUTHN_LEVEL_CALL, + RPC_C_IMP_LEVEL.RPC_C_IMP_LEVEL_IMPERSONATE, + (void*)0, + EOLE_AUTHENTICATION_CAPABILITIES.EOAC_NONE + ); + + if (hr.Failed) + { + Console.WriteLine($"Could not set proxy blanket. Error code = 0x{hr:X}"); + pSvc->Release(); + pLoc->Release(); + PInvoke.CoUninitialize(); + return WmiSearch.Null; + } + + // Perform WMI query to get the Win32_OperatingSystem class + + IEnumWbemClassObject* pEnumerator; + hr = pSvc->ExecQuery( + _strQueryLanguage, + _queryString, + WBEM_GENERIC_FLAG_TYPE.WBEM_FLAG_FORWARD_ONLY | WBEM_GENERIC_FLAG_TYPE.WBEM_RETURN_IMMEDIATELY, + (IWbemContext*)0, + &pEnumerator + ); + + if (hr.Failed) + { + Console.WriteLine($"WMI query failed. Error code = 0x{hr:X}"); + pSvc->Release(); + pLoc->Release(); + PInvoke.CoUninitialize(); + return WmiSearch.Null; + } + + return new WmiSearch( + pSvc, pLoc, pEnumerator, _timeout); + } + + public void Close() + { + PInvoke.CoUninitialize(); + } + + + private void ReleaseUnmanagedResources() + { + _managementScope.Dispose(); + _queryString.Dispose(); + } + + private void Dispose(bool disposing) + { + ReleaseUnmanagedResources(); + if (disposing) + { + + } + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + ~ManagementObjectSearcher() + { + Dispose(false); + } + } + + public unsafe ref struct WmiSearchResultItem + { + private readonly IWbemClassObject* _item; + + internal WmiSearchResultItem(IWbemClassObject* item) + { + _item = item; + } + + public unsafe T GetProperty(string name, T defaultValue = default!) + { + VARIANT vtProp = new VARIANT(); + + var hr = _item->Get(name, 0, ref vtProp, (int*)0, (int*)0); + + if (hr.Value == WBEM_E_NOT_FOUND || vtProp.Anonymous.Anonymous.vt == VARENUM.VT_NULL) + { + if (typeof(T) == typeof(string)) + { + return defaultValue ?? (T)(object)string.Empty; + } + + return defaultValue; + } + + hr.ThrowOnFailure(); + + if ((vtProp.Anonymous.Anonymous.vt & VARENUM.VT_ARRAY) == VARENUM.VT_ARRAY) + { + throw new InvalidOperationException( + $"Property {name} is an array of values."); + } + + if (typeof(T) == typeof(string)) + { + if (vtProp.Anonymous.Anonymous.vt != VARENUM.VT_BSTR) + { + throw new InvalidOperationException( + $"Property {name} is of type {vtProp.Anonymous.Anonymous.vt} and not BSTR."); + } + + var strValue = vtProp.Anonymous.Anonymous.Anonymous.bstrVal.AsSpan().ToString(); + + PInvoke.VariantClear(ref vtProp); + + return (T)(object)strValue; + } + + if (typeof(T) == typeof(ushort)) + { + return (T)(object)this.ExtractValue(name, ref vtProp, VARENUM.VT_UI2, PInvoke.VariantToUInt16); + } + + if (typeof(T) == typeof(uint)) + { + return (T)(object)this.ExtractValue(name, ref vtProp, VARENUM.VT_I4, PInvoke.VariantToUInt32); + } + + if (typeof(T) == typeof(int)) + { + return (T)(object)this.ExtractValue(name, ref vtProp, VARENUM.VT_I4, PInvoke.VariantToInt32); + } + + if (typeof(T) == typeof(UInt64)) + { + return (T)(object)this.ExtractValue(name, ref vtProp, VARENUM.VT_UI8, PInvoke.VariantToUInt64); + } + + if (typeof(T) == typeof(byte)) + { + return (T)(object)this.ExtractValue(name, ref vtProp, VARENUM.VT_UI1, + (in VARIANT v, out byte value) => + { + value = v.Anonymous.Anonymous.Anonymous.bVal; + return new HRESULT(0); + }); + } + + if (typeof(T) == typeof(bool)) + { + var boolValue = this.ExtractValue(name, ref vtProp, VARENUM.VT_BOOL, PInvoke.VariantToBoolean); + + return defaultValue; + } + + throw new NotSupportedException($"Type {typeof(T).FullName} is not supported."); + } + + private T ExtractValue(string propertyName, ref VARIANT variant, VARENUM expectedType, ExtractValueDelegate extractFunc) where T:struct + { + if (variant.Anonymous.Anonymous.vt != expectedType) + { + throw new InvalidOperationException( + $"Property {propertyName} is of type {variant.Anonymous.Anonymous.vt} and not {typeof(T).FullName}."); + } + + T value; + extractFunc(in variant, out value); + + PInvoke.VariantClear(ref variant); + + return (T)value; + } + + private T[] ExtractArrayValue(string propertyName, ref VARIANT variant, VARENUM expectedType, ExtractArrayValueDelegate extractFunc) where T : unmanaged + { + if ((variant.Anonymous.Anonymous.vt & expectedType) != expectedType) + { + throw new InvalidOperationException( + $"Property {propertyName} is of type {variant.Anonymous.Anonymous.vt} and not {typeof(T).FullName}."); + } + + Span array = stackalloc T[10]; + extractFunc(in variant, array, out uint length); + + PInvoke.VariantClear(ref variant); + + return array.Slice(0, (int)length).ToArray(); + } + + public unsafe T[] GetArrayProperty(string name) + { + VARIANT vtProp = new VARIANT(); + var hr = _item->Get(name, 0, ref vtProp, (int*)0, (int*)0); + hr.ThrowOnFailure(); + + if (vtProp.Anonymous.Anonymous.vt == VARENUM.VT_NULL) + { + return Array.Empty(); + } + + if ((vtProp.Anonymous.Anonymous.vt & VARENUM.VT_ARRAY) != VARENUM.VT_ARRAY) + { + throw new InvalidOperationException( + $"Property {name} is not an array of values."); + } + + if (typeof(T) == typeof(string)) + { + if ((vtProp.Anonymous.Anonymous.vt & VARENUM.VT_BSTR) != VARENUM.VT_BSTR) + { + throw new InvalidOperationException( + $"Property {name} is of type {vtProp.Anonymous.Anonymous.vt} and not bstr."); + } + + const uint BUFFER_SIZE = 10; + Span buffer = stackalloc PWSTR[(int)BUFFER_SIZE]; + + uint usedBufferLength; + + hr = PInvoke.VariantToStringArray(in vtProp, buffer, out usedBufferLength); + + hr.ThrowOnFailure(); + + var usedArray = buffer.Slice(0, (int)usedBufferLength); + var strArray = new string[usedArray.Length]; + for (var i = 0; i < usedArray.Length; i++) + { + strArray[i] = usedArray[i].AsSpan().ToString(); + } + + return (T[])(object)strArray; + } + + if (typeof(T) == typeof(ushort)) + { + return (T[]) (object) this.ExtractArrayValue(name, ref vtProp, VARENUM.VT_UI2, PInvoke.VariantToUInt16Array); + } + + if (typeof(T) == typeof(int)) + { + return (T[])(object)this.ExtractArrayValue(name, ref vtProp, VARENUM.VT_I4, PInvoke.VariantToInt32Array); + } + + throw new NotSupportedException($"Type {typeof(T).FullName} is not supported."); + } + } + + public unsafe ref struct WmiSearchResultsEnumerator + { + private Memory _currentArray; + private MemoryHandle _currentArrayHandle; + private bool _isCurrentInUse; + private IEnumWbemClassObject* _enumerator; + private readonly int _timeout; + + + internal WmiSearchResultsEnumerator(IEnumWbemClassObject* enumerator, int timeout) + { + _enumerator = enumerator; + _timeout = timeout; + _currentArray = new IntPtr[1]; + _currentArrayHandle = _currentArray.Pin(); + _isCurrentInUse = false; + } + + public WmiSearchResultItem Current + { + get + { + IWbemClassObject** current = (IWbemClassObject**)_currentArrayHandle.Pointer; + + return new(current[0]); + } + } + + public bool MoveNext() + { + uint uReturn = 0; + + if (_isCurrentInUse) + { + IWbemClassObject** current = (IWbemClassObject**)_currentArrayHandle.Pointer; + current[0]->Release(); + + _isCurrentInUse = false; + } + + var array = (IWbemClassObject**)_currentArrayHandle.Pointer; + + var hr = _enumerator->Next(_timeout, 1, array, &uReturn); + + hr.ThrowOnFailure(); + + _isCurrentInUse = uReturn > 0; + + return uReturn > 0; + } + + public void Dispose() + { + if (_isCurrentInUse) + { + IWbemClassObject** current = (IWbemClassObject**)_currentArrayHandle.Pointer; + current[0]->Release(); + + _isCurrentInUse = false; + } + + _currentArrayHandle.Dispose(); + } + } + + public unsafe ref struct WmiSearch + { + private IWbemServices* _wbemServices; + private IWbemLocator* _wbemLocator; + private IEnumWbemClassObject* _wbemEnumerator; + private readonly int _timeout; + + internal WmiSearch(IWbemServices* wbemServices, IWbemLocator* wbemLocator, IEnumWbemClassObject* wbemEnumerator, int timeout) + { + _wbemServices = wbemServices; + _wbemLocator = wbemLocator; + _wbemEnumerator = wbemEnumerator; + _timeout = timeout; + } + + public WmiSearchResultsEnumerator GetEnumerator() + { + return new WmiSearchResultsEnumerator(_wbemEnumerator, _timeout); + } + + public static WmiSearch Null => new WmiSearch(); + + public void Dispose() + { + _wbemServices->Release(); + _wbemLocator->Release(); + _wbemEnumerator->Release(); + } + } +} diff --git a/Hardware.Info.Aot.Windows/NativeMethods.json b/Hardware.Info.Aot.Windows/NativeMethods.json new file mode 100644 index 0000000..730f087 --- /dev/null +++ b/Hardware.Info.Aot.Windows/NativeMethods.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://aka.ms/CsWin32.schema.json", + "allowMarshaling": false, + "comInterop": { + "preserveSigMethods": [ "*" ] + }, + "public": false +} diff --git a/Hardware.Info.Aot.Windows/NativeMethods.txt b/Hardware.Info.Aot.Windows/NativeMethods.txt new file mode 100644 index 0000000..cf28d38 --- /dev/null +++ b/Hardware.Info.Aot.Windows/NativeMethods.txt @@ -0,0 +1,38 @@ +// COM initialization and security +CoInitializeEx +CoInitializeSecurity +CoSetProxyBlanket +CoUninitialize + +// WMI specific COM classes +IWbemLocator +IWbemServices +IWbemClassObject +IEnumWbemClassObject + +// COM helpers +CoCreateInstance +VARIANT +VariantClear +ClearVariantArray +BSTR +SysAllocString +SysFreeString + +VariantToUInt16Array +VariantToStringArray + +VariantToInt16 +VariantToInt32 +VariantToString +VariantToUInt16 +VariantToUInt32 +VariantToUInt64 +VariantToBoolean +VariantToInt32Array + +// Other functions +GlobalMemoryStatusEx +MEMORYSTATUSEX +RtlGetVersion +OSVERSIONINFOEXW diff --git a/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs b/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs new file mode 100644 index 0000000..0e01f8b --- /dev/null +++ b/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs @@ -0,0 +1,829 @@ +using System.Diagnostics; +using System.Net; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; +using Windows.Win32; +using Windows.Win32.Foundation; +using Windows.Win32.Security; +using Windows.Win32.System.Com; +using Hardware.Info.Core; +using Monitor = Hardware.Info.Core.Monitor; + +namespace Hardware.Info.Aot.Windows +{ + internal class PlatformHardwareInfo : PlatformHardwareInfoBase, IPlatformHardwareInfo + { + private readonly MemoryStatus _memoryStatus = new MemoryStatus(); + + private readonly OS _os = new OS(); + + public bool UseAsteriskInWMI { get; set; } + + private readonly string _managementScope = "root\\cimv2"; + private readonly string _managementScopeWmi = "root\\wmi"; + private readonly int _timeout; + + public PlatformHardwareInfo(TimeSpan? enumerationOptionsTimeout = null) + { + InitializeCom(); + + _timeout = enumerationOptionsTimeout.HasValue ? (int)enumerationOptionsTimeout.Value.TotalMilliseconds : Constants.WBEM_INFINITE; + + + GetOs(); + } + + public static Version? GetOsVersionByRtlGetVersion() + { + global::Windows.Win32.System.SystemInformation.OSVERSIONINFOW info = new (); + info.dwOSVersionInfoSize = (uint)Marshal.SizeOf(); + + var result = global::Windows.Wdk.PInvoke.RtlGetVersion(ref info); + + return (result.SeverityCode == NTSTATUS.Severity.Success) + ? new Version((int)info.dwMajorVersion, (int)info.dwMinorVersion, (int)info.dwBuildNumber) + : null; + } + + private unsafe void InitializeCom() + { + HRESULT hr = PInvoke.CoInitializeEx((void*)0, COINIT.COINIT_MULTITHREADED); + + hr.ThrowOnFailure(); + if (hr.Failed) + { + Console.WriteLine($"Failed to initialize COM library. Error code = 0x{hr:X}"); + return; + } + + // Set COM security levels + hr = PInvoke.CoInitializeSecurity( + new PSECURITY_DESCRIPTOR((void*)0), + -1, + (SOLE_AUTHENTICATION_SERVICE*)0, + (void*)0, + RPC_C_AUTHN_LEVEL.RPC_C_AUTHN_LEVEL_DEFAULT, + RPC_C_IMP_LEVEL.RPC_C_IMP_LEVEL_IMPERSONATE, + (void*)0, + EOLE_AUTHENTICATION_CAPABILITIES.EOAC_NONE, + (void*)0 + ); + + if (hr.Failed) + { + Console.WriteLine($"Failed to initialize security. Error code = 0x{hr:X}"); + PInvoke.CoUninitialize(); + return; + } + } + + public void GetOs() + { + string queryString = UseAsteriskInWMI ? "SELECT * FROM Win32_OperatingSystem" + : "SELECT Caption, Version FROM Win32_OperatingSystem"; + using ManagementObjectSearcher mos = new ManagementObjectSearcher(_managementScope, queryString, _timeout); + + foreach (var mo in mos.Get()) + { + _os.Name = mo.GetProperty("Caption"); + _os.VersionString = mo.GetProperty("Version"); + + if (Version.TryParse(_os.VersionString, out Version version)) + _os.Version = version; + } + + if (string.IsNullOrEmpty(_os.Name)) + { + _os.Name = "Windows"; + } + + if (string.IsNullOrEmpty(_os.VersionString)) + { + Version? version = GetOsVersionByRtlGetVersion(); + + if (version != null) + { + _os.Version = version; + _os.VersionString = version.ToString(); + } + } + } + + public OS GetOperatingSystem() + { + return _os; + } + + public MemoryStatus GetMemoryStatus() + { + var _memoryStatusEx = new global::Windows.Win32.System.SystemInformation.MEMORYSTATUSEX(); + _memoryStatusEx.dwLength = (uint)Marshal.SizeOf(); + + if (PInvoke.GlobalMemoryStatusEx(ref _memoryStatusEx)) + { + _memoryStatus.TotalPhysical = _memoryStatusEx.ullTotalPhys; + _memoryStatus.AvailablePhysical = _memoryStatusEx.ullAvailPhys; + _memoryStatus.TotalPageFile = _memoryStatusEx.ullTotalPageFile; + _memoryStatus.AvailablePageFile = _memoryStatusEx.ullAvailPageFile; + _memoryStatus.TotalVirtual = _memoryStatusEx.ullTotalVirtual; + _memoryStatus.AvailableVirtual = _memoryStatusEx.ullAvailVirtual; + _memoryStatus.AvailableExtendedVirtual = _memoryStatusEx.ullAvailExtendedVirtual; + } + + return _memoryStatus; + } + + public static T GetPropertyValue(object obj) where T : struct + { + return (obj == null) ? default : (T)obj; + } + + public static T[] GetPropertyArray(object obj) + { + return (obj is T[] array) ? array : Array.Empty(); + } + + public static string GetPropertyString(object obj) + { + return (obj is string str) ? str : string.Empty; + } + + public static string GetStringFromUInt16Array(ushort[] array) + { + return Encoding.Unicode.GetString(MemoryMarshal.AsBytes(array.AsSpan())); + } + public static string GetStringFromUInt16Array(int[] array) + { + return Encoding.Unicode.GetString(MemoryMarshal.AsBytes(array.AsSpan())); + } + + public List GetBatteryList() + { + List batteryList = new List(); + + string queryString = UseAsteriskInWMI ? "SELECT * FROM Win32_Battery" + : "SELECT FullChargeCapacity, DesignCapacity, BatteryStatus, EstimatedChargeRemaining, EstimatedRunTime, ExpectedLife, MaxRechargeTime, TimeOnBattery, TimeToFullCharge FROM Win32_Battery"; + using ManagementObjectSearcher mos = new ManagementObjectSearcher(_managementScope, queryString, _timeout); + + foreach (var mo in mos.Get()) + { + Battery battery = new Battery + { + FullChargeCapacity = mo.GetProperty("FullChargeCapacity"), + DesignCapacity = mo.GetProperty("DesignCapacity"), + BatteryStatus = (ushort) mo.GetProperty("BatteryStatus"), + EstimatedChargeRemaining = (ushort) mo.GetProperty("EstimatedChargeRemaining"), + EstimatedRunTime = mo.GetProperty("EstimatedRunTime"), + ExpectedLife = mo.GetProperty("ExpectedLife"), + MaxRechargeTime = mo.GetProperty("MaxRechargeTime"), + TimeOnBattery = mo.GetProperty("TimeOnBattery"), + TimeToFullCharge = mo.GetProperty("TimeToFullCharge") + }; + + batteryList.Add(battery); + } + + return batteryList; + } + + public List GetBiosList() + { + List biosList = new List(); + + string queryString = UseAsteriskInWMI ? "SELECT * FROM Win32_BIOS" + : "SELECT Caption, Description, Manufacturer, Name, ReleaseDate, SerialNumber, SoftwareElementID, Version FROM Win32_BIOS"; + using ManagementObjectSearcher mos = new ManagementObjectSearcher(_managementScope, queryString, _timeout); + + foreach (var mo in mos.Get()) + { + BIOS bios = new BIOS + { + Caption = mo.GetProperty("Caption"), + Description = mo.GetProperty("Description"), + Manufacturer = mo.GetProperty("Manufacturer"), + Name = mo.GetProperty("Name"), + ReleaseDate = mo.GetProperty("ReleaseDate"), + SerialNumber = mo.GetProperty("SerialNumber"), + SoftwareElementID = mo.GetProperty("SoftwareElementID"), + Version = mo.GetProperty("Version") + }; + + biosList.Add(bios); + } + + return biosList; + } + + public List GetComputerSystemList() + { + List computerSystemList = new List(); + + string queryString = UseAsteriskInWMI ? "SELECT * FROM Win32_ComputerSystemProduct" + : "SELECT Caption, Description, IdentifyingNumber, Name, SKUNumber, UUID, Vendor, Version FROM Win32_ComputerSystemProduct"; + using ManagementObjectSearcher mos = new ManagementObjectSearcher(_managementScope, queryString, _timeout); + + foreach (var mo in mos.Get()) + { + ComputerSystem computerSystem = new ComputerSystem + { + Caption = mo.GetProperty("Caption"), + Description = mo.GetProperty("Description"), + IdentifyingNumber = mo.GetProperty("IdentifyingNumber"), + Name = mo.GetProperty("Name"), + SKUNumber = mo.GetProperty("SKUNumber"), + UUID = mo.GetProperty("UUID"), + Vendor = mo.GetProperty("Vendor"), + Version = mo.GetProperty("Version") + }; + + computerSystemList.Add(computerSystem); + } + + return computerSystemList; + } + + public List GetCpuList(bool includePercentProcessorTime = true) + { + List cpuList = new List(); + + List cpuCoreList = new List(); + + ulong percentProcessorTime = 0ul; + + if (includePercentProcessorTime) + { + string queryString = UseAsteriskInWMI ? "SELECT * FROM Win32_PerfFormattedData_PerfOS_Processor WHERE Name != '_Total'" + : "SELECT Name, PercentProcessorTime FROM Win32_PerfFormattedData_PerfOS_Processor WHERE Name != '_Total'"; + ManagementObjectSearcher percentProcessorTimeMOS = new ManagementObjectSearcher(_managementScope, queryString, _timeout); + + queryString = UseAsteriskInWMI ? "SELECT * FROM Win32_PerfFormattedData_PerfOS_Processor WHERE Name = '_Total'" + : "SELECT PercentProcessorTime FROM Win32_PerfFormattedData_PerfOS_Processor WHERE Name = '_Total'"; + ManagementObjectSearcher totalPercentProcessorTimeMOS = new ManagementObjectSearcher(_managementScope, queryString, _timeout); + + try + { + foreach (var mo in percentProcessorTimeMOS.Get()) + { + CpuCore core = new CpuCore + { + Name = mo.GetProperty("Name"), + PercentProcessorTime = ulong.Parse(mo.GetProperty("PercentProcessorTime", "0")) + }; + + cpuCoreList.Add(core); + } + + foreach (var mo in totalPercentProcessorTimeMOS.Get()) + { + percentProcessorTime = ulong.Parse(mo.GetProperty("PercentProcessorTime", "0")); + } + } + finally + { + percentProcessorTimeMOS.Dispose(); + + totalPercentProcessorTimeMOS.Dispose(); + } + + if (percentProcessorTime == 0ul) + { + queryString = UseAsteriskInWMI ? "SELECT * FROM Win32_Processor" + : "SELECT LoadPercentage FROM Win32_Processor"; + using ManagementObjectSearcher loadPercentageMOS = new ManagementObjectSearcher(_managementScope, queryString, _timeout); + + foreach (var mo in loadPercentageMOS.Get()) + { + percentProcessorTime = (uint) mo.GetProperty("LoadPercentage"); + } + } + } + + bool isAtLeastWin8 = (_os.Version.Major == 6 && _os.Version.Minor >= 2) || (_os.Version.Major > 6); + + string query = UseAsteriskInWMI ? "SELECT * FROM Win32_Processor" + : isAtLeastWin8 ? "SELECT Caption, CurrentClockSpeed, Description, L2CacheSize, L3CacheSize, Manufacturer, MaxClockSpeed, Name, NumberOfCores, NumberOfLogicalProcessors, ProcessorId, SecondLevelAddressTranslationExtensions, SocketDesignation, VirtualizationFirmwareEnabled, VMMonitorModeExtensions FROM Win32_Processor" + : "SELECT Caption, CurrentClockSpeed, Description, L2CacheSize, L3CacheSize, Manufacturer, MaxClockSpeed, Name, NumberOfCores, NumberOfLogicalProcessors, ProcessorId, SocketDesignation FROM Win32_Processor"; + using ManagementObjectSearcher mos = new ManagementObjectSearcher(_managementScope, query, _timeout); + + float processorPerformance = 100f; + + try + { + using PerformanceCounter cpuCounter = new PerformanceCounter("Processor Information", "% Processor Performance", "_Total"); + processorPerformance = cpuCounter.NextValue(); + System.Threading.Thread.Sleep(1); // the first call to NextValue() always returns 0 + processorPerformance = cpuCounter.NextValue(); + } + catch + { + // Ignore performance counter errors and just assume that it's at 100 % + } + + uint L1InstructionCacheSize = 0; + uint L1DataCacheSize = 0; + // L1 = 3 + // L2 = 4 + // L3 = 5 + query = UseAsteriskInWMI ? "SELECT * FROM Win32_CacheMemory WHERE Level = 3" + : "SELECT CacheType, MaxCacheSize FROM Win32_CacheMemory WHERE Level = 3"; + using ManagementObjectSearcher Win32_CacheMemory = new ManagementObjectSearcher(_managementScope, query, _timeout); + + // Other = 1 + // Unknown = 2 + // Instruction = 3 + // Data = 4 + // Unified = 5 + foreach (var mo in Win32_CacheMemory.Get()) + { + ushort CacheType = (ushort) mo.GetProperty("CacheType"); + uint MaxCacheSize = 1024 * mo.GetProperty("MaxCacheSize"); + + // if CacheType is Other or Unknown + if (L1InstructionCacheSize == 0) + L1InstructionCacheSize = MaxCacheSize; + + // if CacheType is Other or Unknown + if (L1DataCacheSize == 0) + L1DataCacheSize = MaxCacheSize; + + if (CacheType == 3) // Instruction + L1InstructionCacheSize = MaxCacheSize; + + if (CacheType == 4) // Data + L1DataCacheSize = MaxCacheSize; + } + + foreach (var mo in mos.Get()) + { + uint maxClockSpeed = mo.GetProperty("MaxClockSpeed"); + + uint currentClockSpeed = (uint)(maxClockSpeed * (processorPerformance / 100)); + + CPU cpu = new CPU + { + Caption = mo.GetProperty("Caption"), + //CurrentClockSpeed = GetPropertyValue(mo["CurrentClockSpeed"]), https://stackoverflow.com/questions/61802420/unable-to-get-current-cpu-frequency-in-powershell-or-python + CurrentClockSpeed = currentClockSpeed, + Description = mo.GetProperty("Description"), + L1InstructionCacheSize = L1InstructionCacheSize, + L1DataCacheSize = L1DataCacheSize, + L2CacheSize = 1024 * mo.GetProperty("L2CacheSize"), + L3CacheSize = 1024 * mo.GetProperty("L3CacheSize"), + Manufacturer = mo.GetProperty("Manufacturer"), + MaxClockSpeed = maxClockSpeed, + Name = mo.GetProperty("Name"), + NumberOfCores = mo.GetProperty("NumberOfCores"), + NumberOfLogicalProcessors = mo.GetProperty("NumberOfLogicalProcessors"), + ProcessorId = mo.GetProperty("ProcessorId"), + SocketDesignation = mo.GetProperty("SocketDesignation"), + PercentProcessorTime = percentProcessorTime, + CpuCoreList = cpuCoreList + }; + + if (isAtLeastWin8) + { + cpu.SecondLevelAddressTranslationExtensions = mo.GetProperty("SecondLevelAddressTranslationExtensions"); + cpu.VirtualizationFirmwareEnabled = mo.GetProperty("VirtualizationFirmwareEnabled"); + cpu.VMMonitorModeExtensions = mo.GetProperty("VMMonitorModeExtensions"); + } + + cpuList.Add(cpu); + } + + return cpuList; + } + + public override List GetDriveList() + { + List driveList = new List(); + + string queryString = UseAsteriskInWMI ? "SELECT * FROM Win32_DiskDrive" + : "SELECT Caption, Description, DeviceID, FirmwareRevision, Index, Manufacturer, Model, Name, Partitions, SerialNumber, Size FROM Win32_DiskDrive"; + using ManagementObjectSearcher Win32_DiskDrive = new ManagementObjectSearcher(_managementScope, queryString, _timeout); + + foreach (var DiskDrive in Win32_DiskDrive.Get()) + { + Drive drive = new Drive + { + Caption = DiskDrive.GetProperty("Caption"), + Description = DiskDrive.GetProperty("Description"), + FirmwareRevision = DiskDrive.GetProperty("FirmwareRevision"), + Index = DiskDrive.GetProperty("Index"), + Manufacturer = DiskDrive.GetProperty("Manufacturer"), + Model = DiskDrive.GetProperty("Model"), + Name = DiskDrive.GetProperty("Name"), + Partitions = DiskDrive.GetProperty("Partitions"), + SerialNumber = DiskDrive.GetProperty("SerialNumber"), + Size = ulong.Parse(DiskDrive.GetProperty("Size", "0")) + }; + + string deviceId = DiskDrive.GetProperty("DeviceID"); + string queryString1 = "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + deviceId + "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition"; + using ManagementObjectSearcher Win32_DiskPartition = new ManagementObjectSearcher(_managementScope, queryString1, _timeout); + + foreach (var DiskPartition in Win32_DiskPartition.Get()) + { + Partition partition = new Partition + { + Bootable = DiskPartition.GetProperty("Bootable"), + BootPartition = DiskPartition.GetProperty("BootPartition"), + Caption = DiskPartition.GetProperty("Caption"), + Description = DiskPartition.GetProperty("Description"), + DiskIndex = DiskPartition.GetProperty("DiskIndex"), + Index = DiskPartition.GetProperty("Index"), + Name = DiskPartition.GetProperty("Name"), + PrimaryPartition = DiskPartition.GetProperty("PrimaryPartition"), + Size = ulong.CreateTruncating(UInt128.Parse(DiskPartition.GetProperty("Size", "0"))), + StartingOffset = ulong.Parse(DiskPartition.GetProperty("StartingOffset")) + }; + + var partitionDeviceId = DiskPartition.GetProperty("DeviceID"); + string queryString2 = "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" + partitionDeviceId + "'} WHERE AssocClass = Win32_LogicalDiskToPartition"; + using ManagementObjectSearcher Win32_LogicalDisk = new ManagementObjectSearcher(_managementScope, queryString2, _timeout); + + foreach (var LogicalDisk in Win32_LogicalDisk.Get()) + { + Volume volume = new Volume + { + Caption = LogicalDisk.GetProperty("Caption"), + Compressed = LogicalDisk.GetProperty("Compressed"), + Description = LogicalDisk.GetProperty("Description"), + FileSystem = LogicalDisk.GetProperty("FileSystem"), + FreeSpace = ulong.CreateTruncating(ulong.Parse(LogicalDisk.GetProperty("FreeSpace"))), + Name = LogicalDisk.GetProperty("Name"), + Size = ulong.CreateTruncating(ulong.Parse(LogicalDisk.GetProperty("Size"))), + VolumeName = LogicalDisk.GetProperty("VolumeName"), + VolumeSerialNumber = LogicalDisk.GetProperty("VolumeSerialNumber") + }; + + partition.VolumeList.Add(volume); + } + + drive.PartitionList.Add(partition); + } + + driveList.Add(drive); + } + + return driveList; + } + + public List GetKeyboardList() + { + List keyboardList = new List(); + + string queryString = UseAsteriskInWMI ? "SELECT * FROM Win32_Keyboard" + : "SELECT Caption, Description, Name, NumberOfFunctionKeys FROM Win32_Keyboard"; + using ManagementObjectSearcher mos = new ManagementObjectSearcher(_managementScope, queryString, _timeout); + + foreach (var mo in mos.Get()) + { + Keyboard keyboard = new Keyboard + { + Caption = mo.GetProperty("Caption"), + Description = mo.GetProperty("Description"), + Name = mo.GetProperty("Name"), + NumberOfFunctionKeys = (ushort) mo.GetProperty("NumberOfFunctionKeys") + }; + + keyboardList.Add(keyboard); + } + + return keyboardList; + } + + public List GetMemoryList() + { + List memoryList = new List(); + + string queryString = UseAsteriskInWMI ? "SELECT * FROM Win32_PhysicalMemory" + : _os.Version.Major >= 10 ? "SELECT BankLabel, Capacity, FormFactor, Manufacturer, MaxVoltage, MinVoltage, PartNumber, SerialNumber, Speed FROM Win32_PhysicalMemory" + : "SELECT BankLabel, Capacity, FormFactor, Manufacturer, PartNumber, SerialNumber, Speed FROM Win32_PhysicalMemory"; + using ManagementObjectSearcher mos = new ManagementObjectSearcher(_managementScope, queryString, _timeout); + + foreach (var mo in mos.Get()) + { + Memory memory = new Memory + { + BankLabel = mo.GetProperty("BankLabel"), + Capacity = ulong.Parse(mo.GetProperty("Capacity")), + FormFactor = (FormFactor)mo.GetProperty("FormFactor"), + Manufacturer = mo.GetProperty("Manufacturer"), + PartNumber = mo.GetProperty("PartNumber"), + SerialNumber = mo.GetProperty("SerialNumber"), + Speed = mo.GetProperty("Speed") + }; + + if (_os.Version.Major >= 10) + { + memory.MaxVoltage = mo.GetProperty("MaxVoltage"); + memory.MinVoltage = mo.GetProperty("MinVoltage"); + } + + memoryList.Add(memory); + } + + return memoryList; + } + + public List GetMonitorList() + { + List monitorList = new List(); + + string win32PnpEntityQuery = UseAsteriskInWMI ? "SELECT * FROM Win32_PnPEntity WHERE PNPClass='Monitor'" + : "SELECT DeviceId FROM Win32_PnPEntity WHERE PNPClass='Monitor'"; + using ManagementObjectSearcher win32PnpEntityMos = new ManagementObjectSearcher(_managementScope, win32PnpEntityQuery, _timeout); + + foreach (var win32PnpEntityMo in win32PnpEntityMos.Get()) + { + string deviceId = win32PnpEntityMo.GetProperty("DeviceId"); + string win32DesktopMonitorQuery = UseAsteriskInWMI ? $"SELECT * FROM Win32_DesktopMonitor WHERE PNPDeviceId='{deviceId}'" + : $"SELECT Caption, Description, MonitorManufacturer, MonitorType, Name, PixelsPerXLogicalInch, PixelsPerYLogicalInch FROM Win32_DesktopMonitor WHERE PNPDeviceId='{deviceId}'"; + using ManagementObjectSearcher win32DesktopMonitorMos = new ManagementObjectSearcher(_managementScope, win32DesktopMonitorQuery.Replace(@"\", @"\\"), _timeout); + + string wmiMonitorIdQuery = UseAsteriskInWMI ? $"SELECT * FROM WmiMonitorID WHERE InstanceName LIKE '{deviceId}%'" + : $"SELECT Active, ProductCodeID, SerialNumberID, ManufacturerName, UserFriendlyName, WeekOfManufacture, YearOfManufacture FROM WmiMonitorID WHERE InstanceName LIKE '{deviceId}%'"; + using ManagementObjectSearcher wmiMonitorIdMos = new ManagementObjectSearcher(_managementScopeWmi, wmiMonitorIdQuery.Replace(@"\", "_"), _timeout); + + Monitor monitor = new Monitor(); + + foreach (var desktopMonitorMo in win32DesktopMonitorMos.Get()) + { + monitor.Caption = desktopMonitorMo.GetProperty("Caption"); + monitor.Description = desktopMonitorMo.GetProperty("Description"); + monitor.MonitorManufacturer = desktopMonitorMo.GetProperty("MonitorManufacturer"); + monitor.MonitorType = desktopMonitorMo.GetProperty("MonitorType"); + monitor.Name = desktopMonitorMo.GetProperty("Name"); + monitor.PixelsPerXLogicalInch = desktopMonitorMo.GetProperty("PixelsPerXLogicalInch"); + monitor.PixelsPerYLogicalInch = desktopMonitorMo.GetProperty("PixelsPerYLogicalInch"); + + break; + } + + foreach (var wmiMonitorIdMo in wmiMonitorIdMos.Get()) + { + monitor.Active = wmiMonitorIdMo.GetProperty("Active"); + monitor.ProductCodeID = GetStringFromUInt16Array(wmiMonitorIdMo.GetArrayProperty("ProductCodeID")); + monitor.UserFriendlyName = GetStringFromUInt16Array(wmiMonitorIdMo.GetArrayProperty("UserFriendlyName")); + monitor.SerialNumberID = GetStringFromUInt16Array(wmiMonitorIdMo.GetArrayProperty("SerialNumberID")); + monitor.ManufacturerName = GetStringFromUInt16Array(wmiMonitorIdMo.GetArrayProperty("ManufacturerName")); + monitor.WeekOfManufacture = (ushort) wmiMonitorIdMo.GetProperty("WeekOfManufacture"); + monitor.YearOfManufacture = (ushort) wmiMonitorIdMo.GetProperty("YearOfManufacture"); + + break; + } + + monitorList.Add(monitor); + } + + return monitorList; + } + + public List GetMotherboardList() + { + List motherboardList = new List(); + + string queryString = UseAsteriskInWMI ? "SELECT * FROM Win32_BaseBoard" + : "SELECT Manufacturer, Product, SerialNumber FROM Win32_BaseBoard"; + using ManagementObjectSearcher mos = new ManagementObjectSearcher(_managementScope, queryString, _timeout); + + foreach (var mo in mos.Get()) + { + Motherboard motherboard = new Motherboard + { + Manufacturer = mo.GetProperty("Manufacturer"), + Product = mo.GetProperty("Product"), + SerialNumber = mo.GetProperty("SerialNumber") + }; + + motherboardList.Add(motherboard); + } + + return motherboardList; + } + + public List GetMouseList() + { + List mouseList = new List(); + + string queryString = UseAsteriskInWMI ? "SELECT * FROM Win32_PointingDevice" + : "SELECT Caption, Description, Manufacturer, Name, NumberOfButtons FROM Win32_PointingDevice"; + using ManagementObjectSearcher mos = new ManagementObjectSearcher(_managementScope, queryString, _timeout); + + foreach (var mo in mos.Get()) + { + Mouse mouse = new Mouse + { + Caption = mo.GetProperty("Caption"), + Description = mo.GetProperty("Description"), + Manufacturer = mo.GetProperty("Manufacturer"), + Name = mo.GetProperty("Name"), + NumberOfButtons = mo.GetProperty("NumberOfButtons") + }; + + mouseList.Add(mouse); + } + + return mouseList; + } + + public override List GetNetworkAdapterList(bool includeBytesPersec = true, bool includeNetworkAdapterConfiguration = true) + { + List networkAdapterList = new List(); + + string queryString = UseAsteriskInWMI ? "SELECT * FROM Win32_NetworkAdapter WHERE PhysicalAdapter=True AND MACAddress IS NOT NULL" + : "SELECT AdapterType, Caption, Description, DeviceID, MACAddress, Manufacturer, Name, NetConnectionID, ProductName, Speed FROM Win32_NetworkAdapter WHERE PhysicalAdapter=True AND MACAddress IS NOT NULL"; + using ManagementObjectSearcher mos = new ManagementObjectSearcher(_managementScope, queryString, _timeout); + + foreach (var mo in mos.Get()) + { + NetworkAdapter networkAdapter = new NetworkAdapter + { + AdapterType = mo.GetProperty("AdapterType"), + Caption = mo.GetProperty("Caption"), + Description = mo.GetProperty("Description"), + MACAddress = mo.GetProperty("MACAddress"), + Manufacturer = mo.GetProperty("Manufacturer"), + Name = mo.GetProperty("Name"), + NetConnectionID = mo.GetProperty("NetConnectionID"), + ProductName = mo.GetProperty("ProductName"), + Speed = ulong.Parse(mo.GetProperty("Speed")) + }; + + if (includeBytesPersec) + { + // https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.performancecounter.instancename + + string name = networkAdapter.Name.Replace('(', '[').Replace(')', ']').Replace('#', '_').Replace('\\', '_').Replace('/', '_'); + + string query = UseAsteriskInWMI ? $"SELECT * FROM Win32_PerfFormattedData_Tcpip_NetworkAdapter WHERE Name = '{name}'" + : $"SELECT BytesSentPersec, BytesReceivedPersec, CurrentBandwidth FROM Win32_PerfFormattedData_Tcpip_NetworkAdapter WHERE Name = '{name}'"; + using ManagementObjectSearcher managementObjectSearcher = new ManagementObjectSearcher(_managementScope, query, _timeout); + + foreach (var managementObject in managementObjectSearcher.Get()) + { + networkAdapter.BytesSentPersec = ulong.Parse(managementObject.GetProperty("BytesSentPersec")); + networkAdapter.BytesReceivedPersec = ulong.Parse(managementObject.GetProperty("BytesReceivedPersec")); + + if (networkAdapter.Speed == 0 || networkAdapter.Speed == long.MaxValue) + { + networkAdapter.Speed = managementObject.GetProperty("CurrentBandwidth"); + } + } + } + + if (includeNetworkAdapterConfiguration) + { + IPAddress address; + + string query = $"ASSOCIATORS OF {{{mo.GetProperty("__RelPath")}}} where resultclass = Win32_NetworkAdapterConfiguration"; + + using ManagementObjectSearcher managementObjectSearcher = new ManagementObjectSearcher(_managementScope, query, _timeout); + + + foreach (var configuration in managementObjectSearcher.Get()) + { + foreach (string str in configuration.GetArrayProperty("DefaultIPGateway")) + if (IPAddress.TryParse(str, out address)) + networkAdapter.DefaultIPGatewayList.Add(address); + + if (IPAddress.TryParse(configuration.GetProperty("DHCPServer"), out address)) + networkAdapter.DHCPServer = address; + + foreach (string str in configuration.GetArrayProperty("DNSServerSearchOrder")) + if (IPAddress.TryParse(str, out address)) + networkAdapter.DNSServerSearchOrderList.Add(address); + + foreach (string str in configuration.GetArrayProperty("IPAddress")) + if (IPAddress.TryParse(str, out address)) + networkAdapter.IPAddressList.Add(address); + + foreach (string str in configuration.GetArrayProperty("IPSubnet")) + if (IPAddress.TryParse(str, out address)) + networkAdapter.IPSubnetList.Add(address); + } + } + + networkAdapterList.Add(networkAdapter); + } + + return networkAdapterList; + } + + public List GetPrinterList() + { + List printerList = new List(); + + string queryString = UseAsteriskInWMI ? "SELECT * FROM Win32_Printer" + : "SELECT Caption, Default, Description, HorizontalResolution, Local, Name, Network, Shared, VerticalResolution FROM Win32_Printer"; + using ManagementObjectSearcher mos = new ManagementObjectSearcher(_managementScope, queryString, _timeout); + + foreach (var mo in mos.Get()) + { + Printer printer = new Printer + { + Caption = mo.GetProperty("Caption"), + Default = mo.GetProperty("Default"), + Description = mo.GetProperty("Description"), + HorizontalResolution = mo.GetProperty("HorizontalResolution"), + Local = mo.GetProperty("Local"), + Name = mo.GetProperty("Name"), + Network = mo.GetProperty("Network"), + Shared = mo.GetProperty("Shared"), + VerticalResolution = mo.GetProperty("VerticalResolution") }; + + printerList.Add(printer); + } + + return printerList; + } + + public List GetSoundDeviceList() + { + List soundDeviceList = new List(); + + string queryString = UseAsteriskInWMI ? "SELECT * FROM Win32_SoundDevice WHERE NOT Manufacturer='Microsoft'" + : "SELECT Caption, Description, Manufacturer, Name, ProductName FROM Win32_SoundDevice WHERE NOT Manufacturer='Microsoft'"; + using ManagementObjectSearcher mos = new ManagementObjectSearcher(_managementScope, queryString, _timeout); + + foreach (var mo in mos.Get()) + { + SoundDevice soundDevice = new SoundDevice + { + Caption = mo.GetProperty("Caption"), + Description = mo.GetProperty("Description"), + Manufacturer = mo.GetProperty("Manufacturer"), + Name = mo.GetProperty("Name"), + ProductName = mo.GetProperty("ProductName") + }; + + soundDeviceList.Add(soundDevice); + } + + return soundDeviceList; + } + + public List GetVideoControllerList() + { + List videoControllerList = new List(); + + string queryString = UseAsteriskInWMI ? "SELECT * FROM Win32_VideoController" + : "SELECT AdapterCompatibility, AdapterRAM, Caption, CurrentBitsPerPixel, CurrentHorizontalResolution, CurrentNumberOfColors, CurrentRefreshRate, CurrentVerticalResolution, Description, DriverDate, DriverVersion, MaxRefreshRate, MinRefreshRate, Name, PNPDeviceID, VideoModeDescription, VideoProcessor FROM Win32_VideoController"; + using ManagementObjectSearcher mos = new ManagementObjectSearcher(_managementScope, queryString, _timeout); + + foreach (var mo in mos.Get()) + { + VideoController videoController = new VideoController + { + Manufacturer = mo.GetProperty("AdapterCompatibility"), + AdapterRAM = mo.GetProperty("AdapterRAM"), + Caption = mo.GetProperty("Caption"), + CurrentBitsPerPixel = mo.GetProperty("CurrentBitsPerPixel"), + CurrentHorizontalResolution = mo.GetProperty("CurrentHorizontalResolution"), + CurrentNumberOfColors = UInt64.Parse(mo.GetProperty("CurrentNumberOfColors")), + CurrentRefreshRate = mo.GetProperty("CurrentRefreshRate"), + CurrentVerticalResolution = mo.GetProperty("CurrentVerticalResolution"), + Description = mo.GetProperty("Description"), + DriverDate = mo.GetProperty("DriverDate"), + DriverVersion = mo.GetProperty("DriverVersion"), + MaxRefreshRate = mo.GetProperty("MaxRefreshRate"), + MinRefreshRate = mo.GetProperty("MinRefreshRate"), + Name = mo.GetProperty("Name"), + VideoModeDescription = mo.GetProperty("VideoModeDescription"), + VideoProcessor = mo.GetProperty("VideoProcessor") + }; + + try + { + string deviceID = mo.GetProperty("PNPDeviceID"); + + if (string.IsNullOrEmpty(deviceID)) + continue; + + object? driverObject = Microsoft.Win32.Registry.GetValue(@$"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\{deviceID}", "Driver", default(string)); + + if (driverObject is string driver && !string.IsNullOrEmpty(driver)) + { + object? qwMemorySizeObject = Microsoft.Win32.Registry.GetValue(@$"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{driver}", "HardwareInformation.qwMemorySize", default(long)); + + if (qwMemorySizeObject is long qwMemorySize && qwMemorySize != 0L) + { + videoController.AdapterRAM = (ulong)qwMemorySize; + } + } + } + catch (SecurityException) + { + } + catch (UnauthorizedAccessException) + { + } + + videoControllerList.Add(videoController); + } + + return videoControllerList; + } + } +} diff --git a/Hardware.Info.Aot/Hardware.Info.Aot.csproj b/Hardware.Info.Aot/Hardware.Info.Aot.csproj new file mode 100644 index 0000000..2a7d34b --- /dev/null +++ b/Hardware.Info.Aot/Hardware.Info.Aot.csproj @@ -0,0 +1,43 @@ + + + + net8.0 + 8.0 + enable + + + + Hardware.Info.Aot + Hardware.Info.Aot + 100.1.1.1 + 100.1.1.1 + Jinjinov + Battery, BIOS, CPU - processor, storage drive, keyboard, RAM - memory, monitor, motherboard, mouse, NIC - network adapter, printer, sound card - audio card, graphics card - video card. Hardware.Info is a .NET Standard 2.0 library and uses WMI on Windows, /dev, /proc, /sys on Linux and sysctl, system_profiler on macOS. + Copyright (c) Jinjinov 2022 + https://github.com/Jinjinov/Hardware.Info + + README.md + Computer;Device;Hardware;Info;Information;NET;Windows;Linux;macOS + + MIT + True + ..\HardwareInfo.snk + true + true + + + + + True + \ + + + + + + + + + + + diff --git a/Hardware.Info.Aot/HardwareInfo.cs b/Hardware.Info.Aot/HardwareInfo.cs new file mode 100644 index 0000000..7c0d08a --- /dev/null +++ b/Hardware.Info.Aot/HardwareInfo.cs @@ -0,0 +1,346 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.NetworkInformation; +using System.Net.Sockets; +using System.Runtime.InteropServices; +using Hardware.Info.Core; + +namespace Hardware.Info.Aot +{ + /// + /// Main Hardware.Info class + /// + public class HardwareInfo : IHardwareInfo + { + /// + /// Operating system + /// + public OS OperatingSystem { get; private set; } = new OS(); + + /// + /// Memory status + /// + public MemoryStatus MemoryStatus { get; private set; } = new MemoryStatus(); + + /// + /// List of + /// + public List BatteryList { get; private set; } = new List(); + + /// + /// List of + /// + public List BiosList { get; private set; } = new List(); + + /// + /// List of + /// + public List ComputerSystemList { get; private set; } = new List(); + + /// + /// List of + /// + public List CpuList { get; private set; } = new List(); + + /// + /// List of + /// + public List DriveList { get; private set; } = new List(); + + /// + /// List of + /// + public List KeyboardList { get; private set; } = new List(); + + /// + /// List of + /// + public List MemoryList { get; private set; } = new List(); + + /// + /// List of + /// + public List MonitorList { get; private set; } = new List(); + + /// + /// List of + /// + public List MotherboardList { get; private set; } = new List(); + + /// + /// List of + /// + public List MouseList { get; private set; } = new List(); + + /// + /// List of + /// + public List NetworkAdapterList { get; private set; } = new List(); + + /// + /// List of + /// + public List PrinterList { get; private set; } = new List(); + + /// + /// List of + /// + public List SoundDeviceList { get; private set; } = new List(); + + /// + /// List of + /// + public List VideoControllerList { get; private set; } = new List(); + + private readonly IPlatformHardwareInfo _platformHardwareInfo = null!; + + /// + /// Main Hardware.Info class + /// + /// causes WMI queries to use SELECT * FROM instead of SELECT with a list of property names + /// sets the Timeout property of the EnumerationOptions in the ManagementObjectSearcher that executes the query. The default value is EnumerationOptions.InfiniteTimeout + public HardwareInfo(bool useAsteriskInWMI = true, TimeSpan? timeoutInWMI = null) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) // Environment.OSVersion.Platform == PlatformID.Win32NT) + { + _platformHardwareInfo = new Hardware.Info.Aot.Windows.PlatformHardwareInfo(timeoutInWMI) { UseAsteriskInWMI = useAsteriskInWMI }; + } + + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) // Environment.OSVersion.Platform == PlatformID.MacOSX) + { + _platformHardwareInfo = new Hardware.Info.Mac.PlatformHardwareInfo(); + } + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) // Environment.OSVersion.Platform == PlatformID.Unix) + { + _platformHardwareInfo = new Hardware.Info.Linux.PlatformHardwareInfo(); + } + } + + /// + /// Refresh all hardware info + /// + public void RefreshAll() + { + RefreshOperatingSystem(); + RefreshMemoryStatus(); + + RefreshBatteryList(); + RefreshBIOSList(); + RefreshComputerSystemList(); + RefreshCPUList(); + RefreshDriveList(); + RefreshKeyboardList(); + RefreshMemoryList(); + RefreshMonitorList(); + RefreshMotherboardList(); + RefreshMouseList(); + RefreshNetworkAdapterList(); + RefreshPrinterList(); + RefreshSoundDeviceList(); + RefreshVideoControllerList(); + } + + /// + /// Refresh operating system info + /// + public void RefreshOperatingSystem() => OperatingSystem = _platformHardwareInfo.GetOperatingSystem(); + + /// + /// Refresh memory status info + /// + public void RefreshMemoryStatus() => MemoryStatus = _platformHardwareInfo.GetMemoryStatus(); + + /// + /// Refresh battery info + /// + public void RefreshBatteryList() => BatteryList = _platformHardwareInfo.GetBatteryList(); + + /// + /// Refresh BIOS info + /// + public void RefreshBIOSList() => BiosList = _platformHardwareInfo.GetBiosList(); + + /// + /// Refresh computer system info + /// + public void RefreshComputerSystemList() => ComputerSystemList = _platformHardwareInfo.GetComputerSystemList(); + + /// + /// Refresh CPU info + /// + /// Include PercentProcessorTime info. This makes the method a bit slower. + public void RefreshCPUList(bool includePercentProcessorTime = true) => CpuList = _platformHardwareInfo.GetCpuList(includePercentProcessorTime); + + /// + /// Refresh drive info + /// + public void RefreshDriveList() => DriveList = _platformHardwareInfo.GetDriveList(); + + /// + /// Refresh keyboard info + /// + public void RefreshKeyboardList() => KeyboardList = _platformHardwareInfo.GetKeyboardList(); + + /// + /// Refresh memory info + /// + public void RefreshMemoryList() => MemoryList = _platformHardwareInfo.GetMemoryList(); + + /// + /// Refresh monitor info + /// + public void RefreshMonitorList() => MonitorList = _platformHardwareInfo.GetMonitorList(); + + /// + /// Refresh motherboard info + /// + public void RefreshMotherboardList() => MotherboardList = _platformHardwareInfo.GetMotherboardList(); + + /// + /// Refresh mouse info + /// + public void RefreshMouseList() => MouseList = _platformHardwareInfo.GetMouseList(); + + /// + /// Refresh network adapter info + /// + /// Include BytesPerSec info. This makes the method a bit slower. + /// Include NetworkAdapterConfiguration info. This makes the method a bit slower. + public void RefreshNetworkAdapterList(bool includeBytesPerSec = true, bool includeNetworkAdapterConfiguration = true) => NetworkAdapterList = _platformHardwareInfo.GetNetworkAdapterList(includeBytesPerSec, includeNetworkAdapterConfiguration); + + /// + /// Refresh printer info + /// + public void RefreshPrinterList() => PrinterList = _platformHardwareInfo.GetPrinterList(); + + /// + /// Refresh sound device info + /// + public void RefreshSoundDeviceList() => SoundDeviceList = _platformHardwareInfo.GetSoundDeviceList(); + + /// + /// Refresh video controller info + /// + public void RefreshVideoControllerList() => VideoControllerList = _platformHardwareInfo.GetVideoControllerList(); + + #region Static + + private static bool _pingInProgress; + private static Action? _onPingComplete; + + /// + /// Ping + /// + /// Host name or address to ping + /// On ping complete callback with "bool success" parameter + public static void Ping(string hostNameOrAddress, Action onPingComplete) + { + if (_pingInProgress) + return; + + _pingInProgress = true; + + _onPingComplete = onPingComplete; + + using Ping pingSender = new Ping(); + pingSender.PingCompleted += new PingCompletedEventHandler(PingCompleted); + + byte[] buffer = Enumerable.Repeat(97, 32).ToArray(); + + int timeout = 12000; + + PingOptions options = new PingOptions(64, true); + + pingSender.SendAsync(hostNameOrAddress, timeout, buffer, options, null); + } + + private static void PingCompleted(object sender, PingCompletedEventArgs e) + { + _pingInProgress = false; + + bool success = true; + + if (e.Cancelled) + success = false; + + if (e.Error != null) + success = false; + + PingReply reply = e.Reply; + + if (reply == null) + success = false; + else if (reply.Status != IPStatus.Success) + success = false; + + _onPingComplete?.Invoke(success); + } + + /// + /// Get local IPv4 addresses + /// + /// Local IPv4 addresses + public static IEnumerable GetLocalIPv4Addresses() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + return NetworkInterface.GetAllNetworkInterfaces() + .SelectMany(networkInterface => networkInterface.GetIPProperties().UnicastAddresses) + .Where(addressInformation => addressInformation.Address.AddressFamily == AddressFamily.InterNetwork) + .Select(addressInformation => addressInformation.Address); + } + else + { + return Dns.GetHostEntry(Dns.GetHostName()).AddressList.Where(ip => ip.AddressFamily == AddressFamily.InterNetwork); + } + } + + /// + /// Get local IPv4 addresses + /// + /// Filter by NetworkInterfaceType + /// Local IPv4 addresses + public static IEnumerable GetLocalIPv4Addresses(NetworkInterfaceType networkInterfaceType) + { + return NetworkInterface.GetAllNetworkInterfaces() + .Where(networkInterface => networkInterface.NetworkInterfaceType == networkInterfaceType) + .SelectMany(networkInterface => networkInterface.GetIPProperties().UnicastAddresses) + .Where(addressInformation => addressInformation.Address.AddressFamily == AddressFamily.InterNetwork) + .Select(addressInformation => addressInformation.Address); + } + + /// + /// Get local IPv4 addresses + /// + /// Filter by OperationalStatus + /// Local IPv4 addresses + public static IEnumerable GetLocalIPv4Addresses(OperationalStatus operationalStatus) + { + return NetworkInterface.GetAllNetworkInterfaces() + .Where(networkInterface => networkInterface.OperationalStatus == operationalStatus) + .SelectMany(networkInterface => networkInterface.GetIPProperties().UnicastAddresses) + .Where(addressInformation => addressInformation.Address.AddressFamily == AddressFamily.InterNetwork) + .Select(addressInformation => addressInformation.Address); + } + + /// + /// Get local IPv4 addresses + /// + /// Filter by NetworkInterfaceType + /// Filter by OperationalStatus + /// Local IPv4 addresses + public static IEnumerable GetLocalIPv4Addresses(NetworkInterfaceType networkInterfaceType, OperationalStatus operationalStatus) + { + return NetworkInterface.GetAllNetworkInterfaces() + .Where(networkInterface => networkInterface.NetworkInterfaceType == networkInterfaceType && networkInterface.OperationalStatus == operationalStatus) + .SelectMany(networkInterface => networkInterface.GetIPProperties().UnicastAddresses) + .Where(addressInformation => addressInformation.Address.AddressFamily == AddressFamily.InterNetwork) + .Select(addressInformation => addressInformation.Address); + } + + #endregion + } +} diff --git a/Hardware.Info/Components/BIOS.cs b/Hardware.Info.Core/Components/BIOS.cs similarity index 98% rename from Hardware.Info/Components/BIOS.cs rename to Hardware.Info.Core/Components/BIOS.cs index 6d698ae..b7b5f63 100644 --- a/Hardware.Info/Components/BIOS.cs +++ b/Hardware.Info.Core/Components/BIOS.cs @@ -2,7 +2,7 @@ // https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-bios -namespace Hardware.Info +namespace Hardware.Info.Core { /// /// WMI class: Win32_BIOS diff --git a/Hardware.Info/Components/Battery.cs b/Hardware.Info.Core/Components/Battery.cs similarity index 99% rename from Hardware.Info/Components/Battery.cs rename to Hardware.Info.Core/Components/Battery.cs index b545633..ace8f45 100644 --- a/Hardware.Info/Components/Battery.cs +++ b/Hardware.Info.Core/Components/Battery.cs @@ -2,7 +2,7 @@ // https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-battery -namespace Hardware.Info +namespace Hardware.Info.Core { /// /// WMI class: Win32_Battery diff --git a/Hardware.Info/Components/CPU.cs b/Hardware.Info.Core/Components/CPU.cs similarity index 99% rename from Hardware.Info/Components/CPU.cs rename to Hardware.Info.Core/Components/CPU.cs index dfdc274..5b74339 100644 --- a/Hardware.Info/Components/CPU.cs +++ b/Hardware.Info.Core/Components/CPU.cs @@ -3,7 +3,7 @@ // https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-processor -namespace Hardware.Info +namespace Hardware.Info.Core { /// /// WMI class: Win32_Processor diff --git a/Hardware.Info/Components/ComputerSystem.cs b/Hardware.Info.Core/Components/ComputerSystem.cs similarity index 98% rename from Hardware.Info/Components/ComputerSystem.cs rename to Hardware.Info.Core/Components/ComputerSystem.cs index 7026162..5e08e83 100644 --- a/Hardware.Info/Components/ComputerSystem.cs +++ b/Hardware.Info.Core/Components/ComputerSystem.cs @@ -2,7 +2,7 @@ // https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-computersystemproduct -namespace Hardware.Info +namespace Hardware.Info.Core { /// /// WMI class: Win32_ComputerSystemProduct diff --git a/Hardware.Info/Components/CpuCore.cs b/Hardware.Info.Core/Components/CpuCore.cs similarity index 98% rename from Hardware.Info/Components/CpuCore.cs rename to Hardware.Info.Core/Components/CpuCore.cs index 0a19d48..59742c8 100644 --- a/Hardware.Info/Components/CpuCore.cs +++ b/Hardware.Info.Core/Components/CpuCore.cs @@ -1,6 +1,6 @@ using System; -namespace Hardware.Info +namespace Hardware.Info.Core { /// /// WMI class: Win32_PerfFormattedData_PerfOS_Processor diff --git a/Hardware.Info/Components/Drive.cs b/Hardware.Info.Core/Components/Drive.cs similarity index 99% rename from Hardware.Info/Components/Drive.cs rename to Hardware.Info.Core/Components/Drive.cs index cccdb96..481e3f6 100644 --- a/Hardware.Info/Components/Drive.cs +++ b/Hardware.Info.Core/Components/Drive.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace Hardware.Info +namespace Hardware.Info.Core { // https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-logicaldisk diff --git a/Hardware.Info/Components/Keyboard.cs b/Hardware.Info.Core/Components/Keyboard.cs similarity index 97% rename from Hardware.Info/Components/Keyboard.cs rename to Hardware.Info.Core/Components/Keyboard.cs index 70ae67c..2725213 100644 --- a/Hardware.Info/Components/Keyboard.cs +++ b/Hardware.Info.Core/Components/Keyboard.cs @@ -2,7 +2,7 @@ // https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-keyboard -namespace Hardware.Info +namespace Hardware.Info.Core { /// /// WMI class: Win32_Keyboard diff --git a/Hardware.Info/Components/Memory.cs b/Hardware.Info.Core/Components/Memory.cs similarity index 99% rename from Hardware.Info/Components/Memory.cs rename to Hardware.Info.Core/Components/Memory.cs index 7065964..0b1dd5e 100644 --- a/Hardware.Info/Components/Memory.cs +++ b/Hardware.Info.Core/Components/Memory.cs @@ -2,7 +2,7 @@ // https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-physicalmemory -namespace Hardware.Info +namespace Hardware.Info.Core { /// /// Implementation form factor for the chip. diff --git a/Hardware.Info/Components/MemoryStatus.cs b/Hardware.Info.Core/Components/MemoryStatus.cs similarity index 98% rename from Hardware.Info/Components/MemoryStatus.cs rename to Hardware.Info.Core/Components/MemoryStatus.cs index 86ddd96..01128ca 100644 --- a/Hardware.Info/Components/MemoryStatus.cs +++ b/Hardware.Info.Core/Components/MemoryStatus.cs @@ -2,7 +2,7 @@ // https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-memorystatusex -namespace Hardware.Info +namespace Hardware.Info.Core { /// /// Memory status diff --git a/Hardware.Info/Components/Monitor.cs b/Hardware.Info.Core/Components/Monitor.cs similarity index 99% rename from Hardware.Info/Components/Monitor.cs rename to Hardware.Info.Core/Components/Monitor.cs index 6128f40..021f5f5 100644 --- a/Hardware.Info/Components/Monitor.cs +++ b/Hardware.Info.Core/Components/Monitor.cs @@ -3,7 +3,7 @@ // https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-desktopmonitor // https://learn.microsoft.com/en-us/windows/win32/wmicoreprov/wmimonitorid -namespace Hardware.Info +namespace Hardware.Info.Core { /// /// WMI classes: Win32_DesktopMonitor And WmiMonitorID diff --git a/Hardware.Info/Components/Motherboard.cs b/Hardware.Info.Core/Components/Motherboard.cs similarity index 97% rename from Hardware.Info/Components/Motherboard.cs rename to Hardware.Info.Core/Components/Motherboard.cs index 5b7c2e3..f6327cf 100644 --- a/Hardware.Info/Components/Motherboard.cs +++ b/Hardware.Info.Core/Components/Motherboard.cs @@ -2,7 +2,7 @@ // https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-baseboard -namespace Hardware.Info +namespace Hardware.Info.Core { /// /// WMI class: Win32_BaseBoard diff --git a/Hardware.Info/Components/Mouse.cs b/Hardware.Info.Core/Components/Mouse.cs similarity index 98% rename from Hardware.Info/Components/Mouse.cs rename to Hardware.Info.Core/Components/Mouse.cs index 21bdfb4..bf3ea19 100644 --- a/Hardware.Info/Components/Mouse.cs +++ b/Hardware.Info.Core/Components/Mouse.cs @@ -2,7 +2,7 @@ // https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-pointingdevice -namespace Hardware.Info +namespace Hardware.Info.Core { /// /// WMI class: Win32_PointingDevice diff --git a/Hardware.Info/Components/NetworkAdapter.cs b/Hardware.Info.Core/Components/NetworkAdapter.cs similarity index 99% rename from Hardware.Info/Components/NetworkAdapter.cs rename to Hardware.Info.Core/Components/NetworkAdapter.cs index bcca6e1..44630b5 100644 --- a/Hardware.Info/Components/NetworkAdapter.cs +++ b/Hardware.Info.Core/Components/NetworkAdapter.cs @@ -4,7 +4,7 @@ // https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-networkadapter -namespace Hardware.Info +namespace Hardware.Info.Core { /// /// WMI class: Win32_NetworkAdapter diff --git a/Hardware.Info/Components/OS.cs b/Hardware.Info.Core/Components/OS.cs similarity index 96% rename from Hardware.Info/Components/OS.cs rename to Hardware.Info.Core/Components/OS.cs index bec42e8..684e6af 100644 --- a/Hardware.Info/Components/OS.cs +++ b/Hardware.Info.Core/Components/OS.cs @@ -1,6 +1,6 @@ using System; -namespace Hardware.Info +namespace Hardware.Info.Core { /// /// Operating System Info diff --git a/Hardware.Info/Components/Printer.cs b/Hardware.Info.Core/Components/Printer.cs similarity index 98% rename from Hardware.Info/Components/Printer.cs rename to Hardware.Info.Core/Components/Printer.cs index ef1baf8..6fc8923 100644 --- a/Hardware.Info/Components/Printer.cs +++ b/Hardware.Info.Core/Components/Printer.cs @@ -2,7 +2,7 @@ // https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-printer -namespace Hardware.Info +namespace Hardware.Info.Core { /// /// WMI class: Win32_Printer diff --git a/Hardware.Info/Components/SoundDevice.cs b/Hardware.Info.Core/Components/SoundDevice.cs similarity index 98% rename from Hardware.Info/Components/SoundDevice.cs rename to Hardware.Info.Core/Components/SoundDevice.cs index b57ea87..151dfb9 100644 --- a/Hardware.Info/Components/SoundDevice.cs +++ b/Hardware.Info.Core/Components/SoundDevice.cs @@ -2,7 +2,7 @@ // https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-sounddevice -namespace Hardware.Info +namespace Hardware.Info.Core { /// /// WMI class: Win32_SoundDevice diff --git a/Hardware.Info/Components/VideoController.cs b/Hardware.Info.Core/Components/VideoController.cs similarity index 99% rename from Hardware.Info/Components/VideoController.cs rename to Hardware.Info.Core/Components/VideoController.cs index 909286c..06d5ec8 100644 --- a/Hardware.Info/Components/VideoController.cs +++ b/Hardware.Info.Core/Components/VideoController.cs @@ -2,7 +2,7 @@ // https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-videocontroller -namespace Hardware.Info +namespace Hardware.Info.Core { /// /// WMI class: Win32_VideoController diff --git a/Hardware.Info.Core/Hardware.Info.Core.csproj b/Hardware.Info.Core/Hardware.Info.Core.csproj new file mode 100644 index 0000000..09bf7bb --- /dev/null +++ b/Hardware.Info.Core/Hardware.Info.Core.csproj @@ -0,0 +1,33 @@ + + + + netstandard2.0 + 8.0 + enable + + + + + <_Parameter1>Hardware.Info + + + <_Parameter1>Hardware.Info.Aot + + + <_Parameter1>Hardware.Info.Core + + + <_Parameter1>Hardware.Info.Linux + + + <_Parameter1>Hardware.Info.Mac + + + <_Parameter1>Hardware.Info.Windows + + + <_Parameter1>Hardware.Info.Aot.Windows + + + + diff --git a/Hardware.Info/IHardwareInfo.cs b/Hardware.Info.Core/IHardwareInfo.cs similarity index 99% rename from Hardware.Info/IHardwareInfo.cs rename to Hardware.Info.Core/IHardwareInfo.cs index 229b054..5e5287c 100644 --- a/Hardware.Info/IHardwareInfo.cs +++ b/Hardware.Info.Core/IHardwareInfo.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using Hardware.Info.Core; namespace Hardware.Info { diff --git a/Hardware.Info/IHardwareInfoRetrieval.cs b/Hardware.Info.Core/IPlatformHardwareInfo.cs similarity index 91% rename from Hardware.Info/IHardwareInfoRetrieval.cs rename to Hardware.Info.Core/IPlatformHardwareInfo.cs index bae4121..11efb8d 100644 --- a/Hardware.Info/IHardwareInfoRetrieval.cs +++ b/Hardware.Info.Core/IPlatformHardwareInfo.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; -namespace Hardware.Info +namespace Hardware.Info.Core { - internal interface IHardwareInfoRetrieval + internal interface IPlatformHardwareInfo { OS GetOperatingSystem(); MemoryStatus GetMemoryStatus(); diff --git a/Hardware.Info/HardwareInfoBase.cs b/Hardware.Info.Core/PlatformHardwareInfoBase.cs similarity index 98% rename from Hardware.Info/HardwareInfoBase.cs rename to Hardware.Info.Core/PlatformHardwareInfoBase.cs index 95cd1da..08d9949 100644 --- a/Hardware.Info/HardwareInfoBase.cs +++ b/Hardware.Info.Core/PlatformHardwareInfoBase.cs @@ -6,9 +6,9 @@ using System.Net.Sockets; using System.Runtime.InteropServices; -namespace Hardware.Info +namespace Hardware.Info.Core { - internal class HardwareInfoBase + internal class PlatformHardwareInfoBase { internal static Process StartProcess(string cmd, string args) { diff --git a/Hardware.Info.Linux/Hardware.Info.Linux.csproj b/Hardware.Info.Linux/Hardware.Info.Linux.csproj new file mode 100644 index 0000000..f5d5894 --- /dev/null +++ b/Hardware.Info.Linux/Hardware.Info.Linux.csproj @@ -0,0 +1,22 @@ + + + + netstandard2.0 + 8.0 + enable + + + + + + + + + <_Parameter1>Hardware.Info + + + <_Parameter1>Hardware.Info.Aot + + + + diff --git a/Hardware.Info/Linux/HardwareInfoRetrieval.cs b/Hardware.Info.Linux/PlatformHardwareInfo.cs similarity index 99% rename from Hardware.Info/Linux/HardwareInfoRetrieval.cs rename to Hardware.Info.Linux/PlatformHardwareInfo.cs index a397be7..4c3b5bc 100644 --- a/Hardware.Info/Linux/HardwareInfoRetrieval.cs +++ b/Hardware.Info.Linux/PlatformHardwareInfo.cs @@ -7,12 +7,13 @@ using System.Net.NetworkInformation; using System.Text.RegularExpressions; using System.Threading.Tasks; +using Hardware.Info.Core; // https://www.binarytides.com/linux-commands-hardware-info/ namespace Hardware.Info.Linux { - internal class HardwareInfoRetrieval : HardwareInfoBase, IHardwareInfoRetrieval + internal class PlatformHardwareInfo : PlatformHardwareInfoBase, IPlatformHardwareInfo { private readonly MemoryStatus _memoryStatus = new MemoryStatus(); diff --git a/Hardware.Info.Mac/Hardware.Info.Mac.csproj b/Hardware.Info.Mac/Hardware.Info.Mac.csproj new file mode 100644 index 0000000..f5d5894 --- /dev/null +++ b/Hardware.Info.Mac/Hardware.Info.Mac.csproj @@ -0,0 +1,22 @@ + + + + netstandard2.0 + 8.0 + enable + + + + + + + + + <_Parameter1>Hardware.Info + + + <_Parameter1>Hardware.Info.Aot + + + + diff --git a/Hardware.Info/Mac/HardwareInfoRetrieval.cs b/Hardware.Info.Mac/PlatformHardwareInfo.cs similarity index 99% rename from Hardware.Info/Mac/HardwareInfoRetrieval.cs rename to Hardware.Info.Mac/PlatformHardwareInfo.cs index 156403c..698234d 100644 --- a/Hardware.Info/Mac/HardwareInfoRetrieval.cs +++ b/Hardware.Info.Mac/PlatformHardwareInfo.cs @@ -5,6 +5,8 @@ using System.Runtime.InteropServices; using System.Text.RegularExpressions; using System.Threading; +using Hardware.Info.Core; +using Monitor = Hardware.Info.Core.Monitor; // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/sysctlbyname.3.html // https://wiki.freepascal.org/Accessing_macOS_System_Information @@ -15,7 +17,7 @@ namespace Hardware.Info.Mac { - internal class HardwareInfoRetrieval : HardwareInfoBase, IHardwareInfoRetrieval + internal class PlatformHardwareInfo : PlatformHardwareInfoBase, IPlatformHardwareInfo { private readonly MemoryStatus _memoryStatus = new MemoryStatus(); diff --git a/Hardware.Info.Test/Hardware.Info.Test.csproj b/Hardware.Info.Test/Hardware.Info.Test.csproj index cfe56c7..d6060d8 100644 --- a/Hardware.Info.Test/Hardware.Info.Test.csproj +++ b/Hardware.Info.Test/Hardware.Info.Test.csproj @@ -8,8 +8,15 @@ false + + + PUBLISH_AOT + + + - + + diff --git a/Hardware.Info.Test/Program.cs b/Hardware.Info.Test/Program.cs index a9f3557..a3a398a 100644 --- a/Hardware.Info.Test/Program.cs +++ b/Hardware.Info.Test/Program.cs @@ -3,6 +3,12 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +#if PUBLISH_AOT +using Hardware.Info.Aot; +#else +using Hardware.Info; +#endif + namespace Hardware.Info.Test { class Program diff --git a/Hardware.Info.Windows/Hardware.Info.Windows.csproj b/Hardware.Info.Windows/Hardware.Info.Windows.csproj new file mode 100644 index 0000000..b42eba0 --- /dev/null +++ b/Hardware.Info.Windows/Hardware.Info.Windows.csproj @@ -0,0 +1,29 @@ + + + + netstandard2.0 + 8.0 + enable + + + + + + + + + + + + + + + + <_Parameter1>Hardware.Info + + + <_Parameter1>Hardware.Info.Aot + + + + diff --git a/Hardware.Info/Windows/HardwareInfoRetrieval.cs b/Hardware.Info.Windows/PlatformHardwareInfo.cs similarity index 99% rename from Hardware.Info/Windows/HardwareInfoRetrieval.cs rename to Hardware.Info.Windows/PlatformHardwareInfo.cs index f3c98da..8d401eb 100644 --- a/Hardware.Info/Windows/HardwareInfoRetrieval.cs +++ b/Hardware.Info.Windows/PlatformHardwareInfo.cs @@ -7,6 +7,7 @@ using System.Runtime.InteropServices; using System.Security; using System.Text; +using Hardware.Info.Core; // https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-osversioninfoexa @@ -33,7 +34,7 @@ public MEMORYSTATUSEX() } } - internal class HardwareInfoRetrieval : HardwareInfoBase, IHardwareInfoRetrieval + internal class PlatformHardwareInfo : PlatformHardwareInfoBase, IPlatformHardwareInfo { private readonly MEMORYSTATUSEX _memoryStatusEx = new MEMORYSTATUSEX(); @@ -47,7 +48,7 @@ internal class HardwareInfoRetrieval : HardwareInfoBase, IHardwareInfoRetrieval private readonly string _managementScopeWmi = "root\\wmi"; private readonly EnumerationOptions _enumerationOptions = new EnumerationOptions() { ReturnImmediately = true, Rewindable = false, Timeout = EnumerationOptions.InfiniteTimeout }; - public HardwareInfoRetrieval(TimeSpan? enumerationOptionsTimeout = null) + public PlatformHardwareInfo(TimeSpan? enumerationOptionsTimeout = null) { if (enumerationOptionsTimeout == null) enumerationOptionsTimeout = EnumerationOptions.InfiniteTimeout; diff --git a/Hardware.Info.sln b/Hardware.Info.sln index 41f7106..ec8be58 100644 --- a/Hardware.Info.sln +++ b/Hardware.Info.sln @@ -9,6 +9,18 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hardware.Info.Test", "Hardw EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hardware.Info.Benchmark", "Hardware.Info.Benchmark\Hardware.Info.Benchmark.csproj", "{1E3DFEB6-2E9B-4BA3-B7FF-4AC79D62F014}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hardware.Info.Core", "Hardware.Info.Core\Hardware.Info.Core.csproj", "{B326043D-56B5-433A-AE0C-2E88D36A23DE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hardware.Info.Linux", "Hardware.Info.Linux\Hardware.Info.Linux.csproj", "{2FD59A79-A837-4F50-9571-E580B4101FFA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hardware.Info.Mac", "Hardware.Info.Mac\Hardware.Info.Mac.csproj", "{CBC5409D-D9F9-40B4-8AD4-D2E4CE0F86C2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hardware.Info.Windows", "Hardware.Info.Windows\Hardware.Info.Windows.csproj", "{B54E0C9F-0C6A-487A-A909-A87C5FAF3BAB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hardware.Info.Aot.Windows", "Hardware.Info.Aot.Windows\Hardware.Info.Aot.Windows.csproj", "{17A8E282-CEC1-4C93-9E73-D18979695E2F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hardware.Info.Aot", "Hardware.Info.Aot\Hardware.Info.Aot.csproj", "{0B6CE34E-F490-4293-9D5E-B6CFF3034055}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -27,6 +39,30 @@ Global {1E3DFEB6-2E9B-4BA3-B7FF-4AC79D62F014}.Debug|Any CPU.Build.0 = Debug|Any CPU {1E3DFEB6-2E9B-4BA3-B7FF-4AC79D62F014}.Release|Any CPU.ActiveCfg = Release|Any CPU {1E3DFEB6-2E9B-4BA3-B7FF-4AC79D62F014}.Release|Any CPU.Build.0 = Release|Any CPU + {B326043D-56B5-433A-AE0C-2E88D36A23DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B326043D-56B5-433A-AE0C-2E88D36A23DE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B326043D-56B5-433A-AE0C-2E88D36A23DE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B326043D-56B5-433A-AE0C-2E88D36A23DE}.Release|Any CPU.Build.0 = Release|Any CPU + {2FD59A79-A837-4F50-9571-E580B4101FFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2FD59A79-A837-4F50-9571-E580B4101FFA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2FD59A79-A837-4F50-9571-E580B4101FFA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2FD59A79-A837-4F50-9571-E580B4101FFA}.Release|Any CPU.Build.0 = Release|Any CPU + {CBC5409D-D9F9-40B4-8AD4-D2E4CE0F86C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CBC5409D-D9F9-40B4-8AD4-D2E4CE0F86C2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CBC5409D-D9F9-40B4-8AD4-D2E4CE0F86C2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CBC5409D-D9F9-40B4-8AD4-D2E4CE0F86C2}.Release|Any CPU.Build.0 = Release|Any CPU + {B54E0C9F-0C6A-487A-A909-A87C5FAF3BAB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B54E0C9F-0C6A-487A-A909-A87C5FAF3BAB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B54E0C9F-0C6A-487A-A909-A87C5FAF3BAB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B54E0C9F-0C6A-487A-A909-A87C5FAF3BAB}.Release|Any CPU.Build.0 = Release|Any CPU + {17A8E282-CEC1-4C93-9E73-D18979695E2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {17A8E282-CEC1-4C93-9E73-D18979695E2F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {17A8E282-CEC1-4C93-9E73-D18979695E2F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {17A8E282-CEC1-4C93-9E73-D18979695E2F}.Release|Any CPU.Build.0 = Release|Any CPU + {0B6CE34E-F490-4293-9D5E-B6CFF3034055}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0B6CE34E-F490-4293-9D5E-B6CFF3034055}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0B6CE34E-F490-4293-9D5E-B6CFF3034055}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0B6CE34E-F490-4293-9D5E-B6CFF3034055}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Hardware.Info/Hardware.Info.csproj b/Hardware.Info/Hardware.Info.csproj index 1544363..eb10861 100644 --- a/Hardware.Info/Hardware.Info.csproj +++ b/Hardware.Info/Hardware.Info.csproj @@ -1,7 +1,7 @@  - net8.0 + netstandard2.0 8.0 enable @@ -21,7 +21,7 @@ MIT True - HardwareInfo.snk + ..\HardwareInfo.snk true true @@ -34,10 +34,10 @@ - - - - + + + + diff --git a/Hardware.Info/HardwareInfo.cs b/Hardware.Info/HardwareInfo.cs index f0f2c52..922e6f9 100644 --- a/Hardware.Info/HardwareInfo.cs +++ b/Hardware.Info/HardwareInfo.cs @@ -5,6 +5,7 @@ using System.Net.NetworkInformation; using System.Net.Sockets; using System.Runtime.InteropServices; +using Hardware.Info.Core; namespace Hardware.Info { @@ -93,7 +94,7 @@ public class HardwareInfo : IHardwareInfo /// public List VideoControllerList { get; private set; } = new List(); - private readonly IHardwareInfoRetrieval _hardwareInfoRetrieval = null!; + private readonly IPlatformHardwareInfo _platformHardwareInfo = null!; /// /// Main Hardware.Info class @@ -104,17 +105,17 @@ public HardwareInfo(bool useAsteriskInWMI = true, TimeSpan? timeoutInWMI = null) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) // Environment.OSVersion.Platform == PlatformID.Win32NT) { - _hardwareInfoRetrieval = new Hardware.Info.Windows.HardwareInfoRetrieval(timeoutInWMI) { UseAsteriskInWMI = useAsteriskInWMI }; + _platformHardwareInfo = new Hardware.Info.Windows.PlatformHardwareInfo(timeoutInWMI) { UseAsteriskInWMI = useAsteriskInWMI }; } if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) // Environment.OSVersion.Platform == PlatformID.MacOSX) { - _hardwareInfoRetrieval = new Hardware.Info.Mac.HardwareInfoRetrieval(); + _platformHardwareInfo = new Hardware.Info.Mac.PlatformHardwareInfo(); } if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) // Environment.OSVersion.Platform == PlatformID.Unix) { - _hardwareInfoRetrieval = new Hardware.Info.Linux.HardwareInfoRetrieval(); + _platformHardwareInfo = new Hardware.Info.Linux.PlatformHardwareInfo(); } } @@ -145,85 +146,85 @@ public void RefreshAll() /// /// Refresh operating system info /// - public void RefreshOperatingSystem() => OperatingSystem = _hardwareInfoRetrieval.GetOperatingSystem(); + public void RefreshOperatingSystem() => OperatingSystem = _platformHardwareInfo.GetOperatingSystem(); /// /// Refresh memory status info /// - public void RefreshMemoryStatus() => MemoryStatus = _hardwareInfoRetrieval.GetMemoryStatus(); + public void RefreshMemoryStatus() => MemoryStatus = _platformHardwareInfo.GetMemoryStatus(); /// /// Refresh battery info /// - public void RefreshBatteryList() => BatteryList = _hardwareInfoRetrieval.GetBatteryList(); + public void RefreshBatteryList() => BatteryList = _platformHardwareInfo.GetBatteryList(); /// /// Refresh BIOS info /// - public void RefreshBIOSList() => BiosList = _hardwareInfoRetrieval.GetBiosList(); + public void RefreshBIOSList() => BiosList = _platformHardwareInfo.GetBiosList(); /// /// Refresh computer system info /// - public void RefreshComputerSystemList() => ComputerSystemList = _hardwareInfoRetrieval.GetComputerSystemList(); + public void RefreshComputerSystemList() => ComputerSystemList = _platformHardwareInfo.GetComputerSystemList(); /// /// Refresh CPU info /// /// Include PercentProcessorTime info. This makes the method a bit slower. - public void RefreshCPUList(bool includePercentProcessorTime = true) => CpuList = _hardwareInfoRetrieval.GetCpuList(includePercentProcessorTime); + public void RefreshCPUList(bool includePercentProcessorTime = true) => CpuList = _platformHardwareInfo.GetCpuList(includePercentProcessorTime); /// /// Refresh drive info /// - public void RefreshDriveList() => DriveList = _hardwareInfoRetrieval.GetDriveList(); + public void RefreshDriveList() => DriveList = _platformHardwareInfo.GetDriveList(); /// /// Refresh keyboard info /// - public void RefreshKeyboardList() => KeyboardList = _hardwareInfoRetrieval.GetKeyboardList(); + public void RefreshKeyboardList() => KeyboardList = _platformHardwareInfo.GetKeyboardList(); /// /// Refresh memory info /// - public void RefreshMemoryList() => MemoryList = _hardwareInfoRetrieval.GetMemoryList(); + public void RefreshMemoryList() => MemoryList = _platformHardwareInfo.GetMemoryList(); /// /// Refresh monitor info /// - public void RefreshMonitorList() => MonitorList = _hardwareInfoRetrieval.GetMonitorList(); + public void RefreshMonitorList() => MonitorList = _platformHardwareInfo.GetMonitorList(); /// /// Refresh motherboard info /// - public void RefreshMotherboardList() => MotherboardList = _hardwareInfoRetrieval.GetMotherboardList(); + public void RefreshMotherboardList() => MotherboardList = _platformHardwareInfo.GetMotherboardList(); /// /// Refresh mouse info /// - public void RefreshMouseList() => MouseList = _hardwareInfoRetrieval.GetMouseList(); + public void RefreshMouseList() => MouseList = _platformHardwareInfo.GetMouseList(); /// /// Refresh network adapter info /// /// Include BytesPerSec info. This makes the method a bit slower. /// Include NetworkAdapterConfiguration info. This makes the method a bit slower. - public void RefreshNetworkAdapterList(bool includeBytesPerSec = true, bool includeNetworkAdapterConfiguration = true) => NetworkAdapterList = _hardwareInfoRetrieval.GetNetworkAdapterList(includeBytesPerSec, includeNetworkAdapterConfiguration); + public void RefreshNetworkAdapterList(bool includeBytesPerSec = true, bool includeNetworkAdapterConfiguration = true) => NetworkAdapterList = _platformHardwareInfo.GetNetworkAdapterList(includeBytesPerSec, includeNetworkAdapterConfiguration); /// /// Refresh printer info /// - public void RefreshPrinterList() => PrinterList = _hardwareInfoRetrieval.GetPrinterList(); + public void RefreshPrinterList() => PrinterList = _platformHardwareInfo.GetPrinterList(); /// /// Refresh sound device info /// - public void RefreshSoundDeviceList() => SoundDeviceList = _hardwareInfoRetrieval.GetSoundDeviceList(); + public void RefreshSoundDeviceList() => SoundDeviceList = _platformHardwareInfo.GetSoundDeviceList(); /// /// Refresh video controller info /// - public void RefreshVideoControllerList() => VideoControllerList = _hardwareInfoRetrieval.GetVideoControllerList(); + public void RefreshVideoControllerList() => VideoControllerList = _platformHardwareInfo.GetVideoControllerList(); #region Static diff --git a/Hardware.Info/HardwareInfo.snk b/HardwareInfo.snk similarity index 100% rename from Hardware.Info/HardwareInfo.snk rename to HardwareInfo.snk From dcc01e9d351ad897dd80041ce175a9f439ca6b56 Mon Sep 17 00:00:00 2001 From: Gitii Date: Sun, 29 Sep 2024 13:43:38 +0200 Subject: [PATCH 12/56] . --- .github/workflows/tests.yml | 12 +++++++++++- .../Hardware.Info.Aot.Windows.csproj | 2 ++ Hardware.Info.Aot/Hardware.Info.Aot.csproj | 8 ++++---- Hardware.Info.Core/Hardware.Info.Core.csproj | 2 +- Hardware.Info.Linux/Hardware.Info.Linux.csproj | 2 +- Hardware.Info.Mac/Hardware.Info.Mac.csproj | 2 +- Hardware.Info.Test/Hardware.Info.Test.csproj | 8 +++----- 7 files changed, 23 insertions(+), 13 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8785d3b..5c0e4f0 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -62,12 +62,22 @@ jobs: - name: Compile ahead-of-time shell: bash run: | + dotnet restore \ + Hardware.Info.Test/Hardware.Info.Test.csproj \ + --configuration Release \ + -r "$RUN_TIME" \ + -p PublishAot=true \ + --verbosity quiet \ + -p:TargetFrameworks=net8.0 + dotnet publish \ Hardware.Info.Test/Hardware.Info.Test.csproj \ + --no-restore \ --configuration Release \ -r "$RUN_TIME" \ -p PublishAot=true \ - --verbosity quiet + --verbosity quiet \ + -p:TargetFrameworks=net8.0 - name: Run tests with aot shell: bash diff --git a/Hardware.Info.Aot.Windows/Hardware.Info.Aot.Windows.csproj b/Hardware.Info.Aot.Windows/Hardware.Info.Aot.Windows.csproj index ae81e92..3965137 100644 --- a/Hardware.Info.Aot.Windows/Hardware.Info.Aot.Windows.csproj +++ b/Hardware.Info.Aot.Windows/Hardware.Info.Aot.Windows.csproj @@ -9,6 +9,8 @@ true true true + + true diff --git a/Hardware.Info.Aot/Hardware.Info.Aot.csproj b/Hardware.Info.Aot/Hardware.Info.Aot.csproj index 2a7d34b..25b6c4c 100644 --- a/Hardware.Info.Aot/Hardware.Info.Aot.csproj +++ b/Hardware.Info.Aot/Hardware.Info.Aot.csproj @@ -34,10 +34,10 @@ - - - - + + + + diff --git a/Hardware.Info.Core/Hardware.Info.Core.csproj b/Hardware.Info.Core/Hardware.Info.Core.csproj index 09bf7bb..c7bd33d 100644 --- a/Hardware.Info.Core/Hardware.Info.Core.csproj +++ b/Hardware.Info.Core/Hardware.Info.Core.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + netstandard2.0;net8.0 8.0 enable diff --git a/Hardware.Info.Linux/Hardware.Info.Linux.csproj b/Hardware.Info.Linux/Hardware.Info.Linux.csproj index f5d5894..a374bdb 100644 --- a/Hardware.Info.Linux/Hardware.Info.Linux.csproj +++ b/Hardware.Info.Linux/Hardware.Info.Linux.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + netstandard2.0;net8.0 8.0 enable diff --git a/Hardware.Info.Mac/Hardware.Info.Mac.csproj b/Hardware.Info.Mac/Hardware.Info.Mac.csproj index f5d5894..a374bdb 100644 --- a/Hardware.Info.Mac/Hardware.Info.Mac.csproj +++ b/Hardware.Info.Mac/Hardware.Info.Mac.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + netstandard2.0;net8.0 8.0 enable diff --git a/Hardware.Info.Test/Hardware.Info.Test.csproj b/Hardware.Info.Test/Hardware.Info.Test.csproj index d6060d8..1cecbfd 100644 --- a/Hardware.Info.Test/Hardware.Info.Test.csproj +++ b/Hardware.Info.Test/Hardware.Info.Test.csproj @@ -5,18 +5,16 @@ net8.0 12.0 enable - false + true - - PUBLISH_AOT - + PUBLISH_AOT - + From 5415e13529e1960affa76a0472acbce89b5f07c5 Mon Sep 17 00:00:00 2001 From: Gitii Date: Sun, 29 Sep 2024 13:49:35 +0200 Subject: [PATCH 13/56] . --- Hardware.Info.Test/Hardware.Info.Test.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Hardware.Info.Test/Hardware.Info.Test.csproj b/Hardware.Info.Test/Hardware.Info.Test.csproj index 1cecbfd..0f36ad2 100644 --- a/Hardware.Info.Test/Hardware.Info.Test.csproj +++ b/Hardware.Info.Test/Hardware.Info.Test.csproj @@ -5,7 +5,7 @@ net8.0 12.0 enable - true + false From ecfc791dd313343243d1d0f4f9a1bc1dac272c4d Mon Sep 17 00:00:00 2001 From: Gitii Date: Sun, 29 Sep 2024 14:01:46 +0200 Subject: [PATCH 14/56] . --- Hardware.Info.Test/Hardware.Info.Test.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Hardware.Info.Test/Hardware.Info.Test.csproj b/Hardware.Info.Test/Hardware.Info.Test.csproj index 0f36ad2..9d62373 100644 --- a/Hardware.Info.Test/Hardware.Info.Test.csproj +++ b/Hardware.Info.Test/Hardware.Info.Test.csproj @@ -14,7 +14,7 @@ - + From 23d93963bd66086005c3519acdc6115f6a0185b5 Mon Sep 17 00:00:00 2001 From: Gitii Date: Sun, 29 Sep 2024 15:59:20 +0200 Subject: [PATCH 15/56] . --- .github/workflows/tests.yml | 52 ++++++++++++- Hardware.Info.Aot/Hardware.Info.Aot.csproj | 15 +++- Hardware.Info.Core/Hardware.Info.Core.csproj | 2 + .../Hardware.Info.Linux.csproj | 2 + Hardware.Info.Mac/Hardware.Info.Mac.csproj | 2 + Hardware.Info.Test/Hardware.Info.Test.csproj | 13 +++- .../Hardware.Info.Windows.csproj | 2 + Hardware.Info/Hardware.Info.csproj | 15 +++- build.sh | 77 +++++++++++++++++++ 9 files changed, 167 insertions(+), 13 deletions(-) create mode 100644 build.sh diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5c0e4f0..1709303 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -8,10 +8,35 @@ on: branches: - main workflow_dispatch: + inputs: + version: + description: The version of the build packages + default: 0.0.1 + type: string jobs: - build: - name: Build on ${{ matrix.os }} (${{ matrix.architecture }}) + build: + name: Build libraries + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Build .net standard package + run: ./build.sh -t netstandard2.0 -v 0.5.1 + + - name: Build .net 8.0 package + run: ./build.sh -t netstandard2.0 -v 0.8.0 --aot + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: nuget-packages + path: ./dist/*.nupkg + + test: + needs: build + name: test on ${{ matrix.os }} (${{ matrix.architecture }}) runs-on: ${{ matrix.os }} strategy: matrix: @@ -25,6 +50,25 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + + - name: Download nuget packages + uses: actions/download-artifact@v4 + with: + name: nuget-packages + + - name: Add local nuget feed + shell: bash + run: | + echo " + + + + + + + + + " > NuGet.config - name: Install deps on linux if: ${{ matrix.os == 'ubuntu-latest' }} @@ -52,6 +96,8 @@ jobs: -r "$RUN_TIME" \ --verbosity quiet \ -p WarningLevel=0 \ + -p PublishAot=false \ + -p PACKAGE_SOURCE=nuget \ -- \ --enable-test-mode \ --expected-compiler jit \ @@ -67,6 +113,7 @@ jobs: --configuration Release \ -r "$RUN_TIME" \ -p PublishAot=true \ + -p PACKAGE_SOURCE=nuget \ --verbosity quiet \ -p:TargetFrameworks=net8.0 @@ -76,6 +123,7 @@ jobs: --configuration Release \ -r "$RUN_TIME" \ -p PublishAot=true \ + -p PACKAGE_SOURCE=nuget \ --verbosity quiet \ -p:TargetFrameworks=net8.0 diff --git a/Hardware.Info.Aot/Hardware.Info.Aot.csproj b/Hardware.Info.Aot/Hardware.Info.Aot.csproj index 25b6c4c..70768df 100644 --- a/Hardware.Info.Aot/Hardware.Info.Aot.csproj +++ b/Hardware.Info.Aot/Hardware.Info.Aot.csproj @@ -34,10 +34,17 @@ - - - - + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/Hardware.Info.Core/Hardware.Info.Core.csproj b/Hardware.Info.Core/Hardware.Info.Core.csproj index c7bd33d..12de048 100644 --- a/Hardware.Info.Core/Hardware.Info.Core.csproj +++ b/Hardware.Info.Core/Hardware.Info.Core.csproj @@ -4,6 +4,8 @@ netstandard2.0;net8.0 8.0 enable + + true diff --git a/Hardware.Info.Linux/Hardware.Info.Linux.csproj b/Hardware.Info.Linux/Hardware.Info.Linux.csproj index a374bdb..6e43227 100644 --- a/Hardware.Info.Linux/Hardware.Info.Linux.csproj +++ b/Hardware.Info.Linux/Hardware.Info.Linux.csproj @@ -4,6 +4,8 @@ netstandard2.0;net8.0 8.0 enable + + true diff --git a/Hardware.Info.Mac/Hardware.Info.Mac.csproj b/Hardware.Info.Mac/Hardware.Info.Mac.csproj index a374bdb..6e43227 100644 --- a/Hardware.Info.Mac/Hardware.Info.Mac.csproj +++ b/Hardware.Info.Mac/Hardware.Info.Mac.csproj @@ -4,6 +4,8 @@ netstandard2.0;net8.0 8.0 enable + + true diff --git a/Hardware.Info.Test/Hardware.Info.Test.csproj b/Hardware.Info.Test/Hardware.Info.Test.csproj index 9d62373..ac4619a 100644 --- a/Hardware.Info.Test/Hardware.Info.Test.csproj +++ b/Hardware.Info.Test/Hardware.Info.Test.csproj @@ -6,15 +6,22 @@ 12.0 enable false + + true PUBLISH_AOT - - - + + + + + + + + diff --git a/Hardware.Info.Windows/Hardware.Info.Windows.csproj b/Hardware.Info.Windows/Hardware.Info.Windows.csproj index b42eba0..869ea67 100644 --- a/Hardware.Info.Windows/Hardware.Info.Windows.csproj +++ b/Hardware.Info.Windows/Hardware.Info.Windows.csproj @@ -4,6 +4,8 @@ netstandard2.0 8.0 enable + + false diff --git a/Hardware.Info/Hardware.Info.csproj b/Hardware.Info/Hardware.Info.csproj index eb10861..d9337df 100644 --- a/Hardware.Info/Hardware.Info.csproj +++ b/Hardware.Info/Hardware.Info.csproj @@ -34,10 +34,17 @@ - - - - + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..c0c74aa --- /dev/null +++ b/build.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash + +set -e + +while [[ $# -gt 0 ]]; do + case $1 in + -v|--version) + VERSION="$2" + shift # past argument + shift # past value + ;; + -t|--target) + TFM="$2" + shift # past argument + shift # past value + ;; + --aot) + AOT=YES + shift # past argument + ;; + -*|--*) + echo "Unknown option $1" + exit 1 + ;; + *) + echo "Unknown argument $1" + exit 1 + ;; + esac +done + +if [[ -z "$TFM" ]]; +then + echo "Option -t|--target is missing" + exit 1; +fi + +if [[ -z "$VERSION" ]]; +then + echo "Option -v|--version is missing" + exit 1; +fi + +if [[ "$AOT" = "YES" ]]; +then + PROJECT="Hardware.Info.Aot/Hardware.Info.Aot.csproj" +else + PROJECT="Hardware.Info/Hardware.Info.csproj" +fi + +echo "Restoring..." +dotnet restore \ + "$PROJECT" \ + --verbosity quiet \ + /p:Warn=0 \ + -p:TargetFrameworks="$TFM" + +echo "Building..." +dotnet build --no-restore \ + "$PROJECT" \ + --configuration Release \ + --verbosity quiet \ + /p:Warn=0 \ + -p:Version="$VERSION" \ + -p:TargetFrameworks="$TFM" + +echo "Package project..." +mkdir -p ./dist +dotnet pack --no-restore \ + "$PROJECT" \ + --configuration Release \ + --verbosity quiet \ + /p:Warn=0 \ + -p:Version="$VERSION" \ + -p:PackageVersion="$VERSION" \ + -p:TargetFrameworks="$TFM" \ + -o ./dist \ No newline at end of file From 743802e2cfc5a253fbcc09f079902e666b04f4ab Mon Sep 17 00:00:00 2001 From: Gitii Date: Sun, 29 Sep 2024 16:01:18 +0200 Subject: [PATCH 16/56] . --- .github/workflows/tests.yml | 34 +++++++++++++++++----------------- .gitignore | 2 ++ 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1709303..f8aff92 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,4 +1,4 @@ -name: Run Tests on all supported platforms +name: Build & Test on: push: @@ -11,28 +11,28 @@ on: inputs: version: description: The version of the build packages - default: 0.0.1 + default: local type: string jobs: build: name: Build libraries runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Build .net standard package - run: ./build.sh -t netstandard2.0 -v 0.5.1 - - - name: Build .net 8.0 package - run: ./build.sh -t netstandard2.0 -v 0.8.0 --aot - - - name: Upload artifacts - uses: actions/upload-artifact@v4 - with: - name: nuget-packages - path: ./dist/*.nupkg + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Build .net standard package + run: ./build.sh -t netstandard2.0 -v 0.5.1 + + - name: Build .net 8.0 package + run: ./build.sh -t netstandard2.0 -v 0.8.0 --aot + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: nuget-packages + path: ./dist/*.nupkg test: needs: build diff --git a/.gitignore b/.gitignore index d002232..906023c 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ .vscode bin obj + +dist From c42b00594aed453d75e1fde204afad9cadf55332 Mon Sep 17 00:00:00 2001 From: Gitii Date: Sun, 29 Sep 2024 16:04:20 +0200 Subject: [PATCH 17/56] . --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f8aff92..9e559dc 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -23,7 +23,7 @@ jobs: uses: actions/checkout@v4 - name: Build .net standard package - run: ./build.sh -t netstandard2.0 -v 0.5.1 + run: chmod +x ./build.sh && ./build.sh -t netstandard2.0 -v 0.5.1 - name: Build .net 8.0 package run: ./build.sh -t netstandard2.0 -v 0.8.0 --aot From 3fb47e842c56f1660ad080d614f125eda83d1d98 Mon Sep 17 00:00:00 2001 From: Gitii Date: Sun, 29 Sep 2024 16:06:09 +0200 Subject: [PATCH 18/56] . --- .github/workflows/tests.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9e559dc..bd79716 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -23,10 +23,14 @@ jobs: uses: actions/checkout@v4 - name: Build .net standard package - run: chmod +x ./build.sh && ./build.sh -t netstandard2.0 -v 0.5.1 + run: chmod +x ./build.sh && ./build.sh -t netstandard2.0 -v $VERSION + env: + VERSION: ${{ inputs.version }} - name: Build .net 8.0 package - run: ./build.sh -t netstandard2.0 -v 0.8.0 --aot + run: ./build.sh -t net8.0 -v $VERSION --aot + env: + VERSION: ${{ inputs.version }} - name: Upload artifacts uses: actions/upload-artifact@v4 From 16034e56851baea7264bfb61a3974ba67cd2e5d3 Mon Sep 17 00:00:00 2001 From: Gitii Date: Sun, 29 Sep 2024 16:07:29 +0200 Subject: [PATCH 19/56] . --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index bd79716..772ada9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -11,7 +11,7 @@ on: inputs: version: description: The version of the build packages - default: local + default: 0.0.1 type: string jobs: From 9c93c0e4e10b4c0862be0283a24bca4267835bbb Mon Sep 17 00:00:00 2001 From: Gitii Date: Sun, 29 Sep 2024 16:10:06 +0200 Subject: [PATCH 20/56] . --- .github/workflows/tests.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 772ada9..29b08b6 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -63,7 +63,8 @@ jobs: - name: Add local nuget feed shell: bash run: | - echo " + cat >./NuGet.config < @@ -72,8 +73,9 @@ jobs: - " > NuGet.config - + + EOL + - name: Install deps on linux if: ${{ matrix.os == 'ubuntu-latest' }} shell: bash From f9dc0c97f45f5ab06d39d4ac537300fffe1d5563 Mon Sep 17 00:00:00 2001 From: Gitii Date: Sun, 29 Sep 2024 16:13:54 +0200 Subject: [PATCH 21/56] . --- .github/workflows/tests.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 29b08b6..156558f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -59,6 +59,7 @@ jobs: uses: actions/download-artifact@v4 with: name: nuget-packages + path: ./dist - name: Add local nuget feed shell: bash @@ -66,13 +67,13 @@ jobs: cat >./NuGet.config < - - - - - - - + + + + + + + EOL @@ -86,7 +87,6 @@ jobs: uses: actions/setup-dotnet@v3 with: dotnet-version: '${{ matrix.dotnet }}' # Adjust the version to the one required by Hardware.Info project - include-prerelease: false # Display installed .NET SDKs - name: Display .NET SDK version From d2e1f2ac3a1cf4f1948f0ce5c9356a06c59f4fca Mon Sep 17 00:00:00 2001 From: Gitii Date: Sun, 29 Sep 2024 16:18:01 +0200 Subject: [PATCH 22/56] . --- .github/workflows/tests.yml | 6 +++--- Hardware.Info.Test/Hardware.Info.Test.csproj | 6 ++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 156558f..55d445c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -103,7 +103,7 @@ jobs: --verbosity quiet \ -p WarningLevel=0 \ -p PublishAot=false \ - -p PACKAGE_SOURCE=nuget \ + -p PackageSource=nuget \ -- \ --enable-test-mode \ --expected-compiler jit \ @@ -119,7 +119,7 @@ jobs: --configuration Release \ -r "$RUN_TIME" \ -p PublishAot=true \ - -p PACKAGE_SOURCE=nuget \ + -p PackageSource=nuget \ --verbosity quiet \ -p:TargetFrameworks=net8.0 @@ -129,7 +129,7 @@ jobs: --configuration Release \ -r "$RUN_TIME" \ -p PublishAot=true \ - -p PACKAGE_SOURCE=nuget \ + -p PackageSource=nuget \ --verbosity quiet \ -p:TargetFrameworks=net8.0 diff --git a/Hardware.Info.Test/Hardware.Info.Test.csproj b/Hardware.Info.Test/Hardware.Info.Test.csproj index ac4619a..e27eba9 100644 --- a/Hardware.Info.Test/Hardware.Info.Test.csproj +++ b/Hardware.Info.Test/Hardware.Info.Test.csproj @@ -8,18 +8,20 @@ false true + + project PUBLISH_AOT - + - + From 1b3467ea5a6ad84e5318d4aab2bd1b625be5a334 Mon Sep 17 00:00:00 2001 From: Gitii Date: Sun, 29 Sep 2024 16:20:35 +0200 Subject: [PATCH 23/56] . --- .github/workflows/tests.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 55d445c..7644276 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -116,7 +116,6 @@ jobs: run: | dotnet restore \ Hardware.Info.Test/Hardware.Info.Test.csproj \ - --configuration Release \ -r "$RUN_TIME" \ -p PublishAot=true \ -p PackageSource=nuget \ From 2e6061290b27fa0280e28c49f9ea838f8421aede Mon Sep 17 00:00:00 2001 From: Gitii Date: Sun, 29 Sep 2024 16:28:25 +0200 Subject: [PATCH 24/56] . --- .github/workflows/tests.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7644276..c26a6d4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -132,6 +132,12 @@ jobs: --verbosity quiet \ -p:TargetFrameworks=net8.0 + - name: Upload compiled artifacts + uses: actions/upload-artifact@v4 + with: + name: test-app-${{ matrix.os }}-${{ matrix.architecture }} + path: ./Hardware.Info.Test/bin/Release/net8.0/$RUN_TIME/publish/Hardware.Info.Test/* + - name: Run tests with aot shell: bash run: | From 7274daee16d4fe20b06eb0e7fee05e0cf2d0bfac Mon Sep 17 00:00:00 2001 From: Gitii Date: Sun, 29 Sep 2024 16:30:47 +0200 Subject: [PATCH 25/56] . --- .github/workflows/tests.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c26a6d4..ec5eb18 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -114,17 +114,8 @@ jobs: - name: Compile ahead-of-time shell: bash run: | - dotnet restore \ - Hardware.Info.Test/Hardware.Info.Test.csproj \ - -r "$RUN_TIME" \ - -p PublishAot=true \ - -p PackageSource=nuget \ - --verbosity quiet \ - -p:TargetFrameworks=net8.0 - dotnet publish \ Hardware.Info.Test/Hardware.Info.Test.csproj \ - --no-restore \ --configuration Release \ -r "$RUN_TIME" \ -p PublishAot=true \ From de7417f936ad8deb1e5c2f0792d01cceff11ce18 Mon Sep 17 00:00:00 2001 From: Gitii Date: Sun, 29 Sep 2024 16:41:58 +0200 Subject: [PATCH 26/56] . --- .github/workflows/tests.yml | 3 +-- Hardware.Info.Test/Hardware.Info.Test.csproj | 3 +-- Hardware.Info.Test/Program.cs | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ec5eb18..3c2a1a1 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -64,7 +64,7 @@ jobs: - name: Add local nuget feed shell: bash run: | - cat >./NuGet.config <./nuget.config < @@ -120,7 +120,6 @@ jobs: -r "$RUN_TIME" \ -p PublishAot=true \ -p PackageSource=nuget \ - --verbosity quiet \ -p:TargetFrameworks=net8.0 - name: Upload compiled artifacts diff --git a/Hardware.Info.Test/Hardware.Info.Test.csproj b/Hardware.Info.Test/Hardware.Info.Test.csproj index e27eba9..db0aa4f 100644 --- a/Hardware.Info.Test/Hardware.Info.Test.csproj +++ b/Hardware.Info.Test/Hardware.Info.Test.csproj @@ -6,9 +6,8 @@ 12.0 enable false - + true true - project diff --git a/Hardware.Info.Test/Program.cs b/Hardware.Info.Test/Program.cs index a3a398a..9ba1645 100644 --- a/Hardware.Info.Test/Program.cs +++ b/Hardware.Info.Test/Program.cs @@ -37,7 +37,7 @@ static int Main(string[] args) if (expectedCompiler == TestSuite.Compiler.Aot && isJit) { - Console.Error.WriteLine($"Expected AOT compiler but was {expectedCompiler}"); + Console.Error.WriteLine($"Expected AOT compiler but was {(isJit ? "JIT" : "AOT")}"); return 1; } From d44f420ceee99af3c8aee3af9c54af0615a6061c Mon Sep 17 00:00:00 2001 From: Gitii Date: Sun, 29 Sep 2024 16:43:50 +0200 Subject: [PATCH 27/56] . --- .github/workflows/tests.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3c2a1a1..6c027eb 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -119,8 +119,7 @@ jobs: --configuration Release \ -r "$RUN_TIME" \ -p PublishAot=true \ - -p PackageSource=nuget \ - -p:TargetFrameworks=net8.0 + -p PackageSource=nuget - name: Upload compiled artifacts uses: actions/upload-artifact@v4 From fe1347279a3305dcb59d0a56079e1fa7a4859dbc Mon Sep 17 00:00:00 2001 From: Gitii Date: Sun, 29 Sep 2024 17:08:02 +0200 Subject: [PATCH 28/56] . --- .github/workflows/tests.yml | 60 ++++++++++++++------ Hardware.Info.Test/Hardware.Info.Test.csproj | 5 ++ Hardware.Info.Test/Program.cs | 13 +++++ 3 files changed, 61 insertions(+), 17 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 6c027eb..c10effb 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -48,10 +48,15 @@ jobs: architecture: [x64] # add arm64 when such runner are available dotnet: ['8.x'] fail-fast: false - env: - RUN_TIME: "${{ fromJson('{ \"ubuntu-latest\": \"linux-x64\", \"windows-latest\": \"win-x64\", \"macos-13\": \"osx-x64\" }')[matrix.os] }}" - + steps: + - name: Known variables + id: knownVariables + run: | + RUN_TIME="${{ fromJson('{ \"ubuntu-latest\": \"linux-x64\", \"windows-latest\": \"win-x64\", \"macos-13\": \"osx-x64\" }')[matrix.os] }}" + echo "runTime=$RUN_TIME" >> "$GITHUB_OUTPUT" + echo "publishDirectory=./Hardware.Info.Test/bin/Release/net8.0/$RUN_TIME/publish" >> "$GITHUB_OUTPUT" + - name: Checkout repository uses: actions/checkout@v4 @@ -92,26 +97,43 @@ jobs: - name: Display .NET SDK version run: dotnet --info - # Run with jit - - name: Run tests with jit + - name: Publish with just-in-time compiler shell: bash run: | - dotnet run \ - --project Hardware.Info.Test/Hardware.Info.Test.csproj \ + dotnet publish \ + Hardware.Info.Test/Hardware.Info.Test.csproj \ --configuration Release \ -r "$RUN_TIME" \ - --verbosity quiet \ - -p WarningLevel=0 \ -p PublishAot=false \ - -p PackageSource=nuget \ - -- \ + -p PackageSource=nuget + env: + RUN_TIME: ${{ steps.knownVariables.outcome.runTime }} + + - name: Upload jit compiled test app + uses: actions/upload-artifact@v4 + with: + name: test-app-jit-${{ matrix.os }}-${{ matrix.architecture }} + path: ${{ steps.knownVariables.outputs.publishDirectory }}/* + + - name: Verify hardware info are fetched is using just-in-time compiler + shell: bash + run: | + $PUBLISH_DIR/Hardware.Info.Test \ --enable-test-mode \ --expected-compiler jit \ --expected-arch ${{ matrix.architecture }} \ --no-readline | tee ./output.jit + env: + PUBLISH_DIR: ${{ steps.knownVariables.outputs.publishDirectory }} + + - name: Clean up + shell: bash + run: dotnet clean \ + Hardware.Info.Test/Hardware.Info.Test.csproj && \ + rm -rf ./Hardware.Info.Test/bin/Release # Run with aot - - name: Compile ahead-of-time + - name: Publish with ahead-of-time compiler shell: bash run: | dotnet publish \ @@ -120,21 +142,25 @@ jobs: -r "$RUN_TIME" \ -p PublishAot=true \ -p PackageSource=nuget + env: + RUN_TIME: ${{ steps.knownVariables.outcome.runTime }} - - name: Upload compiled artifacts + - name: Upload aot compiled test app uses: actions/upload-artifact@v4 with: - name: test-app-${{ matrix.os }}-${{ matrix.architecture }} - path: ./Hardware.Info.Test/bin/Release/net8.0/$RUN_TIME/publish/Hardware.Info.Test/* + name: test-app-aot-${{ matrix.os }}-${{ matrix.architecture }} + path: ${{ steps.knownVariables.outputs.publishDirectory }}/* - - name: Run tests with aot + - name: Verify hardware info are fetched is using ahead-of-time compiler shell: bash run: | - ./Hardware.Info.Test/bin/Release/net8.0/$RUN_TIME/publish/Hardware.Info.Test \ + $PUBLISH_DIR/Hardware.Info.Test \ --enable-test-mode \ --expected-compiler aot \ --expected-arch ${{ matrix.architecture }} \ --no-readline | tee ./output.aot + env: + PUBLISH_DIR: ${{ steps.knownVariables.outputs.publishDirectory }} - name: Verify that output is identical if: ${{ false }} diff --git a/Hardware.Info.Test/Hardware.Info.Test.csproj b/Hardware.Info.Test/Hardware.Info.Test.csproj index db0aa4f..182156e 100644 --- a/Hardware.Info.Test/Hardware.Info.Test.csproj +++ b/Hardware.Info.Test/Hardware.Info.Test.csproj @@ -14,6 +14,11 @@ PUBLISH_AOT + + + PACKAGE_SOURCE_NUGET + PACKAGE_SOURCE_PROJECT + diff --git a/Hardware.Info.Test/Program.cs b/Hardware.Info.Test/Program.cs index 9ba1645..68b82d3 100644 --- a/Hardware.Info.Test/Program.cs +++ b/Hardware.Info.Test/Program.cs @@ -28,6 +28,19 @@ static int Main(string[] args) Console.Error.WriteLine($"Compiler: {(isJit ? "JIT" : "AOT")}"); Console.Error.WriteLine($"Expected Compiler: {expectedCompiler}"); Console.Error.WriteLine($"Expected Architecture: {expectedArch}"); +#if PUBLISH_AOT + Console.Error.WriteLine($"Preprocessor Flags: publishAot=true"); +#else + Console.Error.WriteLine($"Preprocessor Flags: publishAot=false"); +#endif + +#if PACKAGE_SOURCE_NUGET + Console.Error.WriteLine($"Preprocessor Flags: packageSource=nuget"); +#endif + +#if PACKAGE_SOURCE_PROJECT + Console.Error.WriteLine($"Preprocessor Flags: packageSource=project"); +#endif if (expectedCompiler == TestSuite.Compiler.Jit && !isJit) { From d8740711f78bb125d66419d99735d552d086c54b Mon Sep 17 00:00:00 2001 From: Gitii Date: Sun, 29 Sep 2024 17:11:33 +0200 Subject: [PATCH 29/56] . --- .github/workflows/tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c10effb..1eedeee 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -52,6 +52,7 @@ jobs: steps: - name: Known variables id: knownVariables + shell: bash run: | RUN_TIME="${{ fromJson('{ \"ubuntu-latest\": \"linux-x64\", \"windows-latest\": \"win-x64\", \"macos-13\": \"osx-x64\" }')[matrix.os] }}" echo "runTime=$RUN_TIME" >> "$GITHUB_OUTPUT" From efa1be5acb1975f0e0449f77611b40934ddb289e Mon Sep 17 00:00:00 2001 From: Gitii Date: Sun, 29 Sep 2024 17:16:21 +0200 Subject: [PATCH 30/56] . --- .github/workflows/tests.yml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1eedeee..f086a3b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -54,7 +54,21 @@ jobs: id: knownVariables shell: bash run: | - RUN_TIME="${{ fromJson('{ \"ubuntu-latest\": \"linux-x64\", \"windows-latest\": \"win-x64\", \"macos-13\": \"osx-x64\" }')[matrix.os] }}" + case "${{ matrix.os }}" in + "ubuntu-latest") + RUN_TIME="linux-x64" + ;; + "windows-latest") + RUN_TIME="win-x64" + ;; + "macos-13") + RUN_TIME="osx-x64" + ;; + *) + echo "Unknown operating system" + exit 1 + ;; + esac echo "runTime=$RUN_TIME" >> "$GITHUB_OUTPUT" echo "publishDirectory=./Hardware.Info.Test/bin/Release/net8.0/$RUN_TIME/publish" >> "$GITHUB_OUTPUT" From ce9a0563ff073a99f91a5b5ed8dfb5765e1e7b61 Mon Sep 17 00:00:00 2001 From: Gitii Date: Sun, 29 Sep 2024 17:19:30 +0200 Subject: [PATCH 31/56] . --- .github/workflows/tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f086a3b..32e7ff3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -122,7 +122,7 @@ jobs: -p PublishAot=false \ -p PackageSource=nuget env: - RUN_TIME: ${{ steps.knownVariables.outcome.runTime }} + RUN_TIME: ${{ steps.knownVariables.outputs.runTime }} - name: Upload jit compiled test app uses: actions/upload-artifact@v4 @@ -158,7 +158,7 @@ jobs: -p PublishAot=true \ -p PackageSource=nuget env: - RUN_TIME: ${{ steps.knownVariables.outcome.runTime }} + RUN_TIME: ${{ steps.knownVariables.outputs.runTime }} - name: Upload aot compiled test app uses: actions/upload-artifact@v4 From 1ab5b7763004d1b7c19ca4332af44f228695b4e8 Mon Sep 17 00:00:00 2001 From: Gitii Date: Sun, 29 Sep 2024 17:25:20 +0200 Subject: [PATCH 32/56] . --- .github/workflows/tests.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 32e7ff3..b9c3081 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -143,9 +143,7 @@ jobs: - name: Clean up shell: bash - run: dotnet clean \ - Hardware.Info.Test/Hardware.Info.Test.csproj && \ - rm -rf ./Hardware.Info.Test/bin/Release + run: rm -rf ./Hardware.Info.Test/bin/Release # Run with aot - name: Publish with ahead-of-time compiler From 76c13b6677be70d97a5578cfb114f54a1e50a2f3 Mon Sep 17 00:00:00 2001 From: Gitii Date: Sun, 29 Sep 2024 17:26:29 +0200 Subject: [PATCH 33/56] . --- Hardware.Info.Test/Hardware.Info.Test.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Hardware.Info.Test/Hardware.Info.Test.csproj b/Hardware.Info.Test/Hardware.Info.Test.csproj index 182156e..91f5025 100644 --- a/Hardware.Info.Test/Hardware.Info.Test.csproj +++ b/Hardware.Info.Test/Hardware.Info.Test.csproj @@ -6,7 +6,7 @@ 12.0 enable false - true + false true project From 6e6b7609d2da0ce573fc678e6b547fca4f3dd79e Mon Sep 17 00:00:00 2001 From: Gitii Date: Sun, 29 Sep 2024 17:46:35 +0200 Subject: [PATCH 34/56] . --- Hardware.Info.Test/Hardware.Info.Test.csproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Hardware.Info.Test/Hardware.Info.Test.csproj b/Hardware.Info.Test/Hardware.Info.Test.csproj index 91f5025..2789cce 100644 --- a/Hardware.Info.Test/Hardware.Info.Test.csproj +++ b/Hardware.Info.Test/Hardware.Info.Test.csproj @@ -8,19 +8,19 @@ false false true - project - PUBLISH_AOT + $(DefineConstants);PUBLISH_AOT - PACKAGE_SOURCE_NUGET - PACKAGE_SOURCE_PROJECT + $(DefineConstants);PACKAGE_SOURCE_NUGET + $(DefineConstants);PACKAGE_SOURCE_PROJECT + From 9469e1686abb398a673d8a804a7a869ca5ae701c Mon Sep 17 00:00:00 2001 From: Gitii Date: Sun, 29 Sep 2024 17:48:30 +0200 Subject: [PATCH 35/56] . --- Hardware.Info.Test/Hardware.Info.Test.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/Hardware.Info.Test/Hardware.Info.Test.csproj b/Hardware.Info.Test/Hardware.Info.Test.csproj index 2789cce..f9019c1 100644 --- a/Hardware.Info.Test/Hardware.Info.Test.csproj +++ b/Hardware.Info.Test/Hardware.Info.Test.csproj @@ -6,7 +6,6 @@ 12.0 enable false - false true From 73fe6cbef24c5f37a8ed9c06ecddf6488e23ff2d Mon Sep 17 00:00:00 2001 From: Gitii Date: Sun, 29 Sep 2024 17:57:11 +0200 Subject: [PATCH 36/56] . --- Hardware.Info.Aot/Hardware.Info.Aot.csproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Hardware.Info.Aot/Hardware.Info.Aot.csproj b/Hardware.Info.Aot/Hardware.Info.Aot.csproj index 70768df..81908f4 100644 --- a/Hardware.Info.Aot/Hardware.Info.Aot.csproj +++ b/Hardware.Info.Aot/Hardware.Info.Aot.csproj @@ -45,6 +45,9 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + + + From 082bd5fffde43930ab80c1d5300d23d44bcd3536 Mon Sep 17 00:00:00 2001 From: Gitii Date: Thu, 3 Oct 2024 12:24:59 +0200 Subject: [PATCH 37/56] fix merge conflict issues --- Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs | 5 ++--- Hardware.Info.Aot/HardwareInfo.cs | 13 +++++++++---- .../Hardware.Info.Benchmark.csproj | 1 + 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs b/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs index 0e01f8b..c0aed6f 100644 --- a/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs +++ b/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs @@ -243,7 +243,7 @@ public List GetComputerSystemList() return computerSystemList; } - public List GetCpuList(bool includePercentProcessorTime = true) + public List GetCpuList(bool includePercentProcessorTime = true, int millisecondsDelayBetweenTwoMeasurements = 500) { List cpuList = new List(); @@ -628,8 +628,7 @@ public List GetMouseList() return mouseList; } - public override List GetNetworkAdapterList(bool includeBytesPersec = true, bool includeNetworkAdapterConfiguration = true) - { + public override List GetNetworkAdapterList(bool includeBytesPersec = true, bool includeNetworkAdapterConfiguration = true, int millisecondsDelayBetweenTwoMeasurements = 1000) { List networkAdapterList = new List(); string queryString = UseAsteriskInWMI ? "SELECT * FROM Win32_NetworkAdapter WHERE PhysicalAdapter=True AND MACAddress IS NOT NULL" diff --git a/Hardware.Info.Aot/HardwareInfo.cs b/Hardware.Info.Aot/HardwareInfo.cs index 7c0d08a..4729c01 100644 --- a/Hardware.Info.Aot/HardwareInfo.cs +++ b/Hardware.Info.Aot/HardwareInfo.cs @@ -172,8 +172,10 @@ public void RefreshAll() /// Refresh CPU info /// /// Include PercentProcessorTime info. This makes the method a bit slower. - public void RefreshCPUList(bool includePercentProcessorTime = true) => CpuList = _platformHardwareInfo.GetCpuList(includePercentProcessorTime); - + /// Delay in milliseconds between two measurements in Linux + public void RefreshCPUList(bool includePercentProcessorTime = true, int millisecondsDelayBetweenTwoMeasurements = 500) + => CpuList = _platformHardwareInfo.GetCpuList(includePercentProcessorTime, millisecondsDelayBetweenTwoMeasurements); + /// /// Refresh drive info /// @@ -209,8 +211,11 @@ public void RefreshAll() /// /// Include BytesPerSec info. This makes the method a bit slower. /// Include NetworkAdapterConfiguration info. This makes the method a bit slower. - public void RefreshNetworkAdapterList(bool includeBytesPerSec = true, bool includeNetworkAdapterConfiguration = true) => NetworkAdapterList = _platformHardwareInfo.GetNetworkAdapterList(includeBytesPerSec, includeNetworkAdapterConfiguration); - + /// Delay in milliseconds between two measurements in Linux + public void RefreshNetworkAdapterList(bool includeBytesPerSec = true, bool includeNetworkAdapterConfiguration = true, + int millisecondsDelayBetweenTwoMeasurements = 1000) + => NetworkAdapterList = _platformHardwareInfo.GetNetworkAdapterList(includeBytesPerSec, includeNetworkAdapterConfiguration, millisecondsDelayBetweenTwoMeasurements); + /// /// Refresh printer info /// diff --git a/Hardware.Info.Benchmark/Hardware.Info.Benchmark.csproj b/Hardware.Info.Benchmark/Hardware.Info.Benchmark.csproj index 84d2466..33efe3f 100644 --- a/Hardware.Info.Benchmark/Hardware.Info.Benchmark.csproj +++ b/Hardware.Info.Benchmark/Hardware.Info.Benchmark.csproj @@ -12,6 +12,7 @@ + From 23575d0a325ae8a097325351585edc742c00cdff Mon Sep 17 00:00:00 2001 From: Gitii Date: Thu, 3 Oct 2024 12:41:32 +0200 Subject: [PATCH 38/56] handle weird array behaviour --- .../ManagementObjectSearcher.cs | 93 ++++++++++++++++--- .../PlatformHardwareInfo.cs | 25 +++-- 2 files changed, 99 insertions(+), 19 deletions(-) diff --git a/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs b/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs index f74e9a2..23fb429 100644 --- a/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs +++ b/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs @@ -267,39 +267,55 @@ private T[] ExtractArrayValue(string propertyName, ref VARIANT variant, VAREN return array.Slice(0, (int)length).ToArray(); } - public unsafe T[] GetArrayProperty(string name) + public enum ArrayPropertyError + { + None, + NullProperty, + NotArrayType, + UnsupportedType, + InvalidStringType, + InvalidUShortType, + InvalidIntType + } + + public bool TryGetArrayProperty(string name, out T[] value, out ArrayPropertyError errorReason) { VARIANT vtProp = new VARIANT(); var hr = _item->Get(name, 0, ref vtProp, (int*)0, (int*)0); - hr.ThrowOnFailure(); + + // Default the output values + value = Array.Empty(); + errorReason = ArrayPropertyError.None; + + if (hr.Failed) return false; if (vtProp.Anonymous.Anonymous.vt == VARENUM.VT_NULL) { - return Array.Empty(); + errorReason = ArrayPropertyError.NullProperty; + return true; } if ((vtProp.Anonymous.Anonymous.vt & VARENUM.VT_ARRAY) != VARENUM.VT_ARRAY) { - throw new InvalidOperationException( - $"Property {name} is not an array of values."); + errorReason = ArrayPropertyError.NotArrayType; + return false; } if (typeof(T) == typeof(string)) { if ((vtProp.Anonymous.Anonymous.vt & VARENUM.VT_BSTR) != VARENUM.VT_BSTR) { - throw new InvalidOperationException( - $"Property {name} is of type {vtProp.Anonymous.Anonymous.vt} and not bstr."); + errorReason = ArrayPropertyError.InvalidStringType; + return false; } const uint BUFFER_SIZE = 10; Span buffer = stackalloc PWSTR[(int)BUFFER_SIZE]; - uint usedBufferLength; hr = PInvoke.VariantToStringArray(in vtProp, buffer, out usedBufferLength); - hr.ThrowOnFailure(); + if (hr.Failed) return false; var usedArray = buffer.Slice(0, (int)usedBufferLength); var strArray = new string[usedArray.Length]; @@ -308,21 +324,72 @@ public unsafe T[] GetArrayProperty(string name) strArray[i] = usedArray[i].AsSpan().ToString(); } - return (T[])(object)strArray; + value = (T[])(object)strArray; + return true; } if (typeof(T) == typeof(ushort)) { - return (T[]) (object) this.ExtractArrayValue(name, ref vtProp, VARENUM.VT_UI2, PInvoke.VariantToUInt16Array); + value = (T[])(object)this.ExtractArrayValue(name, ref vtProp, VARENUM.VT_UI2, PInvoke.VariantToUInt16Array); + if (value == null) + { + errorReason = ArrayPropertyError.InvalidUShortType; + return false; + } + return true; } if (typeof(T) == typeof(int)) { - return (T[])(object)this.ExtractArrayValue(name, ref vtProp, VARENUM.VT_I4, PInvoke.VariantToInt32Array); + value = (T[])(object)this.ExtractArrayValue(name, ref vtProp, VARENUM.VT_I4, PInvoke.VariantToInt32Array); + if (value == null) + { + errorReason = ArrayPropertyError.InvalidIntType; + return false; + } + return true; + } + + errorReason = ArrayPropertyError.UnsupportedType; + return false; + } + + public static void HandleArrayPropertyError(string name, ArrayPropertyError errorReason) + { + switch (errorReason) + { + case ArrayPropertyError.NullProperty: + return; // Null property is acceptable, just return (equivalent to returning an empty array). + case ArrayPropertyError.NotArrayType: + throw new InvalidOperationException($"Property {name} is not an array of values."); + case ArrayPropertyError.InvalidStringType: + throw new InvalidOperationException($"Property {name} is of type BSTR and not an array of strings."); + case ArrayPropertyError.InvalidUShortType: + throw new InvalidOperationException($"Property {name} is not an array of ushort values."); + case ArrayPropertyError.InvalidIntType: + throw new InvalidOperationException($"Property {name} is not an array of int values."); + case ArrayPropertyError.UnsupportedType: + throw new NotSupportedException($"Type {typeof(T).FullName} is not supported."); + default: + throw new InvalidOperationException($"Failed to get property {name}."); } + } - throw new NotSupportedException($"Type {typeof(T).FullName} is not supported."); + public T[] GetArrayProperty(string name) + { + if (TryGetArrayProperty(name, out T[] value, out ArrayPropertyError errorReason)) + { + return value; + } + + // Call the new helper function for error handling + HandleArrayPropertyError(name, errorReason); + + // If no exception is thrown, return an empty array (for NullProperty case) + return Array.Empty(); } + + } public unsafe ref struct WmiSearchResultsEnumerator diff --git a/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs b/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs index c0aed6f..c0683ae 100644 --- a/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs +++ b/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs @@ -149,11 +149,11 @@ public static string GetPropertyString(object obj) return (obj is string str) ? str : string.Empty; } - public static string GetStringFromUInt16Array(ushort[] array) + public static string GetStringFromArray(ushort[] array) { return Encoding.Unicode.GetString(MemoryMarshal.AsBytes(array.AsSpan())); } - public static string GetStringFromUInt16Array(int[] array) + public static string GetStringFromArray(int[] array) { return Encoding.Unicode.GetString(MemoryMarshal.AsBytes(array.AsSpan())); } @@ -564,10 +564,23 @@ public List GetMonitorList() foreach (var wmiMonitorIdMo in wmiMonitorIdMos.Get()) { monitor.Active = wmiMonitorIdMo.GetProperty("Active"); - monitor.ProductCodeID = GetStringFromUInt16Array(wmiMonitorIdMo.GetArrayProperty("ProductCodeID")); - monitor.UserFriendlyName = GetStringFromUInt16Array(wmiMonitorIdMo.GetArrayProperty("UserFriendlyName")); - monitor.SerialNumberID = GetStringFromUInt16Array(wmiMonitorIdMo.GetArrayProperty("SerialNumberID")); - monitor.ManufacturerName = GetStringFromUInt16Array(wmiMonitorIdMo.GetArrayProperty("ManufacturerName")); + monitor.ProductCodeID = GetStringFromArray(wmiMonitorIdMo.GetArrayProperty("ProductCodeID")); + if (wmiMonitorIdMo.TryGetArrayProperty("UserFriendlyName", out var userFriendlyNameUint16, + out var errorReason)) + { + monitor.UserFriendlyName = GetStringFromArray(userFriendlyNameUint16); + } else if (wmiMonitorIdMo.TryGetArrayProperty("UserFriendlyName", out var userFriendlyNameInt4, + out _)) + { + monitor.UserFriendlyName = GetStringFromArray(userFriendlyNameInt4); + } + else + { + WmiSearchResultItem.HandleArrayPropertyError("UserFriendlyName", errorReason); + } + monitor.UserFriendlyName = GetStringFromArray(wmiMonitorIdMo.GetArrayProperty("UserFriendlyName")); + monitor.SerialNumberID = GetStringFromArray(wmiMonitorIdMo.GetArrayProperty("SerialNumberID")); + monitor.ManufacturerName = GetStringFromArray(wmiMonitorIdMo.GetArrayProperty("ManufacturerName")); monitor.WeekOfManufacture = (ushort) wmiMonitorIdMo.GetProperty("WeekOfManufacture"); monitor.YearOfManufacture = (ushort) wmiMonitorIdMo.GetProperty("YearOfManufacture"); From d31d9348a6e9803e45f2dfb19c572a9bee982d78 Mon Sep 17 00:00:00 2001 From: Gitii Date: Thu, 3 Oct 2024 12:52:23 +0200 Subject: [PATCH 39/56] fix error handling --- .../ManagementObjectSearcher.cs | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs b/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs index 23fb429..cf2dd62 100644 --- a/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs +++ b/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs @@ -251,14 +251,13 @@ private T ExtractValue(string propertyName, ref VARIANT variant, VARENUM expe return (T)value; } - private T[] ExtractArrayValue(string propertyName, ref VARIANT variant, VARENUM expectedType, ExtractArrayValueDelegate extractFunc) where T : unmanaged + private bool IsVariantOfType(in VARIANT variant, VARENUM expectedType) { - if ((variant.Anonymous.Anonymous.vt & expectedType) != expectedType) - { - throw new InvalidOperationException( - $"Property {propertyName} is of type {variant.Anonymous.Anonymous.vt} and not {typeof(T).FullName}."); - } + return (variant.Anonymous.Anonymous.vt & expectedType) != expectedType; + } + private T[] ExtractArrayValue(ref VARIANT variant, ExtractArrayValueDelegate extractFunc) where T : unmanaged + { Span array = stackalloc T[10]; extractFunc(in variant, array, out uint length); @@ -330,23 +329,26 @@ public bool TryGetArrayProperty(string name, out T[] value, out ArrayProperty if (typeof(T) == typeof(ushort)) { - value = (T[])(object)this.ExtractArrayValue(name, ref vtProp, VARENUM.VT_UI2, PInvoke.VariantToUInt16Array); - if (value == null) + if (!IsVariantOfType(in vtProp, VARENUM.VT_UI2)) { errorReason = ArrayPropertyError.InvalidUShortType; return false; } + + value = (T[])(object)this.ExtractArrayValue(ref vtProp, PInvoke.VariantToUInt16Array); + return true; } if (typeof(T) == typeof(int)) { - value = (T[])(object)this.ExtractArrayValue(name, ref vtProp, VARENUM.VT_I4, PInvoke.VariantToInt32Array); - if (value == null) + if (!IsVariantOfType(in vtProp, VARENUM.VT_I4)) { errorReason = ArrayPropertyError.InvalidIntType; return false; } + + value = (T[])(object)this.ExtractArrayValue(ref vtProp, PInvoke.VariantToInt32Array); return true; } From ad321ac75409e7acb9ec00b36918d89706fa5fc3 Mon Sep 17 00:00:00 2001 From: Gitii Date: Thu, 3 Oct 2024 12:59:07 +0200 Subject: [PATCH 40/56] . --- .github/workflows/tests.yml | 2 +- Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b9c3081..816860b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -104,7 +104,7 @@ jobs: # Setup .NET SDK - name: Setup .NET SDK - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: dotnet-version: '${{ matrix.dotnet }}' # Adjust the version to the one required by Hardware.Info project diff --git a/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs b/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs index cf2dd62..b22d081 100644 --- a/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs +++ b/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs @@ -296,6 +296,7 @@ public bool TryGetArrayProperty(string name, out T[] value, out ArrayProperty if ((vtProp.Anonymous.Anonymous.vt & VARENUM.VT_ARRAY) != VARENUM.VT_ARRAY) { + Console.WriteLine(vtProp.Anonymous.Anonymous.vt + " is not an array"); errorReason = ArrayPropertyError.NotArrayType; return false; } From db1482ce20c97512e447250cdb879fba9d6965f0 Mon Sep 17 00:00:00 2001 From: Gitii Date: Thu, 3 Oct 2024 13:02:57 +0200 Subject: [PATCH 41/56] . --- Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs b/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs index b22d081..fe9aa39 100644 --- a/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs +++ b/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs @@ -296,7 +296,8 @@ public bool TryGetArrayProperty(string name, out T[] value, out ArrayProperty if ((vtProp.Anonymous.Anonymous.vt & VARENUM.VT_ARRAY) != VARENUM.VT_ARRAY) { - Console.WriteLine(vtProp.Anonymous.Anonymous.vt + " is not an array"); + Console.Error.WriteLine(vtProp.Anonymous.Anonymous.vt + " is not an array"); + Console.Error.Flush(); errorReason = ArrayPropertyError.NotArrayType; return false; } From 2b6561dc59a41fb790e06c557ebdf21d5071a4c6 Mon Sep 17 00:00:00 2001 From: Gitii Date: Thu, 3 Oct 2024 13:07:12 +0200 Subject: [PATCH 42/56] . --- Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs b/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs index fe9aa39..62842f7 100644 --- a/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs +++ b/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs @@ -346,6 +346,8 @@ public bool TryGetArrayProperty(string name, out T[] value, out ArrayProperty { if (!IsVariantOfType(in vtProp, VARENUM.VT_I4)) { + Console.Error.WriteLine(vtProp.Anonymous.Anonymous.vt + " is not an int array"); + Console.Error.Flush(); errorReason = ArrayPropertyError.InvalidIntType; return false; } From 1bee91b91d3615e4c42bf3f2d5dfe0814cafb4cd Mon Sep 17 00:00:00 2001 From: Gitii Date: Thu, 3 Oct 2024 13:10:41 +0200 Subject: [PATCH 43/56] . --- Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs b/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs index 62842f7..0df1db3 100644 --- a/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs +++ b/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs @@ -253,7 +253,7 @@ private T ExtractValue(string propertyName, ref VARIANT variant, VARENUM expe private bool IsVariantOfType(in VARIANT variant, VARENUM expectedType) { - return (variant.Anonymous.Anonymous.vt & expectedType) != expectedType; + return (variant.Anonymous.Anonymous.vt & expectedType) == expectedType; } private T[] ExtractArrayValue(ref VARIANT variant, ExtractArrayValueDelegate extractFunc) where T : unmanaged From 5c4e3c8bfa867daaae2703699d319b41fe32b879 Mon Sep 17 00:00:00 2001 From: Gitii Date: Thu, 3 Oct 2024 13:23:10 +0200 Subject: [PATCH 44/56] . --- .../ManagementObjectSearcher.cs | 87 +++++++++++++++---- .../PlatformHardwareInfo.cs | 4 +- 2 files changed, 71 insertions(+), 20 deletions(-) diff --git a/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs b/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs index 0df1db3..d26fdbc 100644 --- a/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs +++ b/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs @@ -176,6 +176,8 @@ public unsafe T GetProperty(string name, T defaultValue = default!) if ((vtProp.Anonymous.Anonymous.vt & VARENUM.VT_ARRAY) == VARENUM.VT_ARRAY) { + PInvoke.VariantClear(ref vtProp); + throw new InvalidOperationException( $"Property {name} is an array of values."); } @@ -184,6 +186,8 @@ public unsafe T GetProperty(string name, T defaultValue = default!) { if (vtProp.Anonymous.Anonymous.vt != VARENUM.VT_BSTR) { + PInvoke.VariantClear(ref vtProp); + throw new InvalidOperationException( $"Property {name} is of type {vtProp.Anonymous.Anonymous.vt} and not BSTR."); } @@ -197,40 +201,64 @@ public unsafe T GetProperty(string name, T defaultValue = default!) if (typeof(T) == typeof(ushort)) { - return (T)(object)this.ExtractValue(name, ref vtProp, VARENUM.VT_UI2, PInvoke.VariantToUInt16); + var value = (T)(object)this.ExtractValue(name, ref vtProp, VARENUM.VT_UI2, PInvoke.VariantToUInt16); + + PInvoke.VariantClear(ref vtProp); + + return value; } if (typeof(T) == typeof(uint)) { - return (T)(object)this.ExtractValue(name, ref vtProp, VARENUM.VT_I4, PInvoke.VariantToUInt32); + var value = (T)(object)this.ExtractValue(name, ref vtProp, VARENUM.VT_I4, PInvoke.VariantToUInt32); + + PInvoke.VariantClear(ref vtProp); + + return value; } if (typeof(T) == typeof(int)) { - return (T)(object)this.ExtractValue(name, ref vtProp, VARENUM.VT_I4, PInvoke.VariantToInt32); + var value = (T)(object)this.ExtractValue(name, ref vtProp, VARENUM.VT_I4, PInvoke.VariantToInt32); + + PInvoke.VariantClear(ref vtProp); + + return value; } if (typeof(T) == typeof(UInt64)) { - return (T)(object)this.ExtractValue(name, ref vtProp, VARENUM.VT_UI8, PInvoke.VariantToUInt64); + var value = (T)(object)this.ExtractValue(name, ref vtProp, VARENUM.VT_UI8, PInvoke.VariantToUInt64); + + PInvoke.VariantClear(ref vtProp); + + return value; } if (typeof(T) == typeof(byte)) { - return (T)(object)this.ExtractValue(name, ref vtProp, VARENUM.VT_UI1, + var value = (T)(object)this.ExtractValue(name, ref vtProp, VARENUM.VT_UI1, (in VARIANT v, out byte value) => { value = v.Anonymous.Anonymous.Anonymous.bVal; return new HRESULT(0); }); + + PInvoke.VariantClear(ref vtProp); + + return value; } if (typeof(T) == typeof(bool)) { var boolValue = this.ExtractValue(name, ref vtProp, VARENUM.VT_BOOL, PInvoke.VariantToBoolean); + + PInvoke.VariantClear(ref vtProp); - return defaultValue; + return (T) (object) (bool) boolValue; } + + PInvoke.VariantClear(ref vtProp); throw new NotSupportedException($"Type {typeof(T).FullName} is not supported."); } @@ -246,8 +274,6 @@ private T ExtractValue(string propertyName, ref VARIANT variant, VARENUM expe T value; extractFunc(in variant, out value); - PInvoke.VariantClear(ref variant); - return (T)value; } @@ -261,8 +287,6 @@ private T[] ExtractArrayValue(ref VARIANT variant, ExtractArrayValueDelegate< Span array = stackalloc T[10]; extractFunc(in variant, array, out uint length); - PInvoke.VariantClear(ref variant); - return array.Slice(0, (int)length).ToArray(); } @@ -274,7 +298,8 @@ public enum ArrayPropertyError UnsupportedType, InvalidStringType, InvalidUShortType, - InvalidIntType + InvalidIntType, + InteropError } public bool TryGetArrayProperty(string name, out T[] value, out ArrayPropertyError errorReason) @@ -286,18 +311,24 @@ public bool TryGetArrayProperty(string name, out T[] value, out ArrayProperty value = Array.Empty(); errorReason = ArrayPropertyError.None; - if (hr.Failed) return false; + if (hr.Failed) + { + errorReason = ArrayPropertyError.InteropError; + return false; + } if (vtProp.Anonymous.Anonymous.vt == VARENUM.VT_NULL) { + PInvoke.VariantClear(ref vtProp); + errorReason = ArrayPropertyError.NullProperty; return true; } if ((vtProp.Anonymous.Anonymous.vt & VARENUM.VT_ARRAY) != VARENUM.VT_ARRAY) { - Console.Error.WriteLine(vtProp.Anonymous.Anonymous.vt + " is not an array"); - Console.Error.Flush(); + PInvoke.VariantClear(ref vtProp); + errorReason = ArrayPropertyError.NotArrayType; return false; } @@ -306,6 +337,8 @@ public bool TryGetArrayProperty(string name, out T[] value, out ArrayProperty { if ((vtProp.Anonymous.Anonymous.vt & VARENUM.VT_BSTR) != VARENUM.VT_BSTR) { + PInvoke.VariantClear(ref vtProp); + errorReason = ArrayPropertyError.InvalidStringType; return false; } @@ -316,7 +349,14 @@ public bool TryGetArrayProperty(string name, out T[] value, out ArrayProperty hr = PInvoke.VariantToStringArray(in vtProp, buffer, out usedBufferLength); - if (hr.Failed) return false; + if (hr.Failed) + { + PInvoke.VariantClear(ref vtProp); + + errorReason = ArrayPropertyError.InteropError; + + return false; + } var usedArray = buffer.Slice(0, (int)usedBufferLength); var strArray = new string[usedArray.Length]; @@ -324,8 +364,10 @@ public bool TryGetArrayProperty(string name, out T[] value, out ArrayProperty { strArray[i] = usedArray[i].AsSpan().ToString(); } - + value = (T[])(object)strArray; + + PInvoke.VariantClear(ref vtProp); return true; } @@ -333,12 +375,15 @@ public bool TryGetArrayProperty(string name, out T[] value, out ArrayProperty { if (!IsVariantOfType(in vtProp, VARENUM.VT_UI2)) { + PInvoke.VariantClear(ref vtProp); + errorReason = ArrayPropertyError.InvalidUShortType; return false; } value = (T[])(object)this.ExtractArrayValue(ref vtProp, PInvoke.VariantToUInt16Array); + PInvoke.VariantClear(ref vtProp); return true; } @@ -346,15 +391,19 @@ public bool TryGetArrayProperty(string name, out T[] value, out ArrayProperty { if (!IsVariantOfType(in vtProp, VARENUM.VT_I4)) { - Console.Error.WriteLine(vtProp.Anonymous.Anonymous.vt + " is not an int array"); - Console.Error.Flush(); + PInvoke.VariantClear(ref vtProp); + errorReason = ArrayPropertyError.InvalidIntType; return false; } value = (T[])(object)this.ExtractArrayValue(ref vtProp, PInvoke.VariantToInt32Array); + + PInvoke.VariantClear(ref vtProp); return true; } + + PInvoke.VariantClear(ref vtProp); errorReason = ArrayPropertyError.UnsupportedType; return false; @@ -376,6 +425,8 @@ public static void HandleArrayPropertyError(string name, ArrayPropertyError e throw new InvalidOperationException($"Property {name} is not an array of int values."); case ArrayPropertyError.UnsupportedType: throw new NotSupportedException($"Type {typeof(T).FullName} is not supported."); + case ArrayPropertyError.InteropError: + throw new NotSupportedException($"Property value from {name} could not be extracted."); default: throw new InvalidOperationException($"Failed to get property {name}."); } diff --git a/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs b/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs index c0683ae..14ecc73 100644 --- a/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs +++ b/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs @@ -566,11 +566,11 @@ public List GetMonitorList() monitor.Active = wmiMonitorIdMo.GetProperty("Active"); monitor.ProductCodeID = GetStringFromArray(wmiMonitorIdMo.GetArrayProperty("ProductCodeID")); if (wmiMonitorIdMo.TryGetArrayProperty("UserFriendlyName", out var userFriendlyNameUint16, - out var errorReason)) + out _)) { monitor.UserFriendlyName = GetStringFromArray(userFriendlyNameUint16); } else if (wmiMonitorIdMo.TryGetArrayProperty("UserFriendlyName", out var userFriendlyNameInt4, - out _)) + out var errorReason)) { monitor.UserFriendlyName = GetStringFromArray(userFriendlyNameInt4); } From 7c6ab81a7a14beeecc0e71471a33dc50d2439674 Mon Sep 17 00:00:00 2001 From: Gitii Date: Thu, 3 Oct 2024 13:33:00 +0200 Subject: [PATCH 45/56] . --- .../ManagementObjectSearcher.cs | 251 ++++++++---------- .../PlatformHardwareInfo.cs | 26 +- 2 files changed, 126 insertions(+), 151 deletions(-) diff --git a/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs b/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs index d26fdbc..be4baad 100644 --- a/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs +++ b/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs @@ -174,93 +174,80 @@ public unsafe T GetProperty(string name, T defaultValue = default!) hr.ThrowOnFailure(); - if ((vtProp.Anonymous.Anonymous.vt & VARENUM.VT_ARRAY) == VARENUM.VT_ARRAY) + try { - PInvoke.VariantClear(ref vtProp); - - throw new InvalidOperationException( - $"Property {name} is an array of values."); - } - - if (typeof(T) == typeof(string)) - { - if (vtProp.Anonymous.Anonymous.vt != VARENUM.VT_BSTR) + if ((vtProp.Anonymous.Anonymous.vt & VARENUM.VT_ARRAY) == VARENUM.VT_ARRAY) { - PInvoke.VariantClear(ref vtProp); - throw new InvalidOperationException( - $"Property {name} is of type {vtProp.Anonymous.Anonymous.vt} and not BSTR."); + $"Property {name} is an array of values."); } - var strValue = vtProp.Anonymous.Anonymous.Anonymous.bstrVal.AsSpan().ToString(); + if (typeof(T) == typeof(string)) + { + if (vtProp.Anonymous.Anonymous.vt != VARENUM.VT_BSTR) + { + throw new InvalidOperationException( + $"Property {name} is of type {vtProp.Anonymous.Anonymous.vt} and not BSTR."); + } - PInvoke.VariantClear(ref vtProp); + var strValue = vtProp.Anonymous.Anonymous.Anonymous.bstrVal.AsSpan().ToString(); + + return (T)(object)strValue; + } - return (T)(object)strValue; - } + if (typeof(T) == typeof(ushort)) + { + var value = (T)(object)this.ExtractValue(name, ref vtProp, VARENUM.VT_UI2, PInvoke.VariantToUInt16); + + return value; + } - if (typeof(T) == typeof(ushort)) - { - var value = (T)(object)this.ExtractValue(name, ref vtProp, VARENUM.VT_UI2, PInvoke.VariantToUInt16); - - PInvoke.VariantClear(ref vtProp); - - return value; - } + if (typeof(T) == typeof(uint)) + { + var value = (T)(object)this.ExtractValue(name, ref vtProp, VARENUM.VT_I4, PInvoke.VariantToUInt32); + + return value; + } - if (typeof(T) == typeof(uint)) - { - var value = (T)(object)this.ExtractValue(name, ref vtProp, VARENUM.VT_I4, PInvoke.VariantToUInt32); - - PInvoke.VariantClear(ref vtProp); - - return value; - } + if (typeof(T) == typeof(int)) + { + var value = (T)(object)this.ExtractValue(name, ref vtProp, VARENUM.VT_I4, PInvoke.VariantToInt32); + + return value; + } - if (typeof(T) == typeof(int)) - { - var value = (T)(object)this.ExtractValue(name, ref vtProp, VARENUM.VT_I4, PInvoke.VariantToInt32); - - PInvoke.VariantClear(ref vtProp); - - return value; - } + if (typeof(T) == typeof(UInt64)) + { + var value = (T)(object)this.ExtractValue(name, ref vtProp, VARENUM.VT_UI8, PInvoke.VariantToUInt64); + + return value; + } - if (typeof(T) == typeof(UInt64)) - { - var value = (T)(object)this.ExtractValue(name, ref vtProp, VARENUM.VT_UI8, PInvoke.VariantToUInt64); - - PInvoke.VariantClear(ref vtProp); - - return value; - } + if (typeof(T) == typeof(byte)) + { + var value = (T)(object)this.ExtractValue(name, ref vtProp, VARENUM.VT_UI1, + (in VARIANT v, out byte value) => + { + value = v.Anonymous.Anonymous.Anonymous.bVal; + return new HRESULT(0); + }); + + return value; + } - if (typeof(T) == typeof(byte)) - { - var value = (T)(object)this.ExtractValue(name, ref vtProp, VARENUM.VT_UI1, - (in VARIANT v, out byte value) => - { - value = v.Anonymous.Anonymous.Anonymous.bVal; - return new HRESULT(0); - }); - - PInvoke.VariantClear(ref vtProp); + if (typeof(T) == typeof(bool)) + { + var boolValue = this.ExtractValue(name, ref vtProp, VARENUM.VT_BOOL, PInvoke.VariantToBoolean); + + return (T) (object) (bool) boolValue; + } - return value; + throw new NotSupportedException($"Type {typeof(T).FullName} is not supported."); } - - if (typeof(T) == typeof(bool)) + finally { - var boolValue = this.ExtractValue(name, ref vtProp, VARENUM.VT_BOOL, PInvoke.VariantToBoolean); - PInvoke.VariantClear(ref vtProp); - - return (T) (object) (bool) boolValue; } - - PInvoke.VariantClear(ref vtProp); - - throw new NotSupportedException($"Type {typeof(T).FullName} is not supported."); } private T ExtractValue(string propertyName, ref VARIANT variant, VARENUM expectedType, ExtractValueDelegate extractFunc) where T:struct @@ -305,6 +292,7 @@ public enum ArrayPropertyError public bool TryGetArrayProperty(string name, out T[] value, out ArrayPropertyError errorReason) { VARIANT vtProp = new VARIANT(); + var hr = _item->Get(name, 0, ref vtProp, (int*)0, (int*)0); // Default the output values @@ -317,96 +305,83 @@ public bool TryGetArrayProperty(string name, out T[] value, out ArrayProperty return false; } - if (vtProp.Anonymous.Anonymous.vt == VARENUM.VT_NULL) - { - PInvoke.VariantClear(ref vtProp); - - errorReason = ArrayPropertyError.NullProperty; - return true; - } - - if ((vtProp.Anonymous.Anonymous.vt & VARENUM.VT_ARRAY) != VARENUM.VT_ARRAY) + try { - PInvoke.VariantClear(ref vtProp); - - errorReason = ArrayPropertyError.NotArrayType; - return false; - } + if (vtProp.Anonymous.Anonymous.vt == VARENUM.VT_NULL) + { + errorReason = ArrayPropertyError.NullProperty; + return true; + } - if (typeof(T) == typeof(string)) - { - if ((vtProp.Anonymous.Anonymous.vt & VARENUM.VT_BSTR) != VARENUM.VT_BSTR) + if ((vtProp.Anonymous.Anonymous.vt & VARENUM.VT_ARRAY) != VARENUM.VT_ARRAY) { - PInvoke.VariantClear(ref vtProp); - - errorReason = ArrayPropertyError.InvalidStringType; + errorReason = ArrayPropertyError.NotArrayType; return false; } - const uint BUFFER_SIZE = 10; - Span buffer = stackalloc PWSTR[(int)BUFFER_SIZE]; - uint usedBufferLength; + if (typeof(T) == typeof(string)) + { + if ((vtProp.Anonymous.Anonymous.vt & VARENUM.VT_BSTR) != VARENUM.VT_BSTR) + { + errorReason = ArrayPropertyError.InvalidStringType; + return false; + } - hr = PInvoke.VariantToStringArray(in vtProp, buffer, out usedBufferLength); + const uint BUFFER_SIZE = 10; + Span buffer = stackalloc PWSTR[(int)BUFFER_SIZE]; + uint usedBufferLength; - if (hr.Failed) - { - PInvoke.VariantClear(ref vtProp); + hr = PInvoke.VariantToStringArray(in vtProp, buffer, out usedBufferLength); - errorReason = ArrayPropertyError.InteropError; + if (hr.Failed) + { + errorReason = ArrayPropertyError.InteropError; - return false; + return false; + } + + var usedArray = buffer.Slice(0, (int)usedBufferLength); + var strArray = new string[usedArray.Length]; + for (var i = 0; i < usedArray.Length; i++) + { + strArray[i] = usedArray[i].AsSpan().ToString(); + } + + value = (T[])(object)strArray; + return true; } - var usedArray = buffer.Slice(0, (int)usedBufferLength); - var strArray = new string[usedArray.Length]; - for (var i = 0; i < usedArray.Length; i++) + if (typeof(T) == typeof(ushort)) { - strArray[i] = usedArray[i].AsSpan().ToString(); - } - - value = (T[])(object)strArray; + if (!IsVariantOfType(in vtProp, VARENUM.VT_UI2)) + { + errorReason = ArrayPropertyError.InvalidUShortType; + return false; + } - PInvoke.VariantClear(ref vtProp); - return true; - } + value = (T[])(object)this.ExtractArrayValue(ref vtProp, PInvoke.VariantToUInt16Array); + return true; + } - if (typeof(T) == typeof(ushort)) - { - if (!IsVariantOfType(in vtProp, VARENUM.VT_UI2)) + if (typeof(T) == typeof(int)) { - PInvoke.VariantClear(ref vtProp); - - errorReason = ArrayPropertyError.InvalidUShortType; - return false; - } + if (!IsVariantOfType(in vtProp, VARENUM.VT_I4)) + { + errorReason = ArrayPropertyError.InvalidIntType; + return false; + } - value = (T[])(object)this.ExtractArrayValue(ref vtProp, PInvoke.VariantToUInt16Array); + value = (T[])(object)this.ExtractArrayValue(ref vtProp, PInvoke.VariantToInt32Array); + return true; + } - PInvoke.VariantClear(ref vtProp); - return true; + errorReason = ArrayPropertyError.UnsupportedType; + return false; } - - if (typeof(T) == typeof(int)) + finally { - if (!IsVariantOfType(in vtProp, VARENUM.VT_I4)) - { - PInvoke.VariantClear(ref vtProp); - - errorReason = ArrayPropertyError.InvalidIntType; - return false; - } - - value = (T[])(object)this.ExtractArrayValue(ref vtProp, PInvoke.VariantToInt32Array); - PInvoke.VariantClear(ref vtProp); - return true; } - - PInvoke.VariantClear(ref vtProp); - - errorReason = ArrayPropertyError.UnsupportedType; - return false; } public static void HandleArrayPropertyError(string name, ArrayPropertyError errorReason) diff --git a/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs b/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs index 14ecc73..c4dce71 100644 --- a/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs +++ b/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs @@ -565,19 +565,19 @@ public List GetMonitorList() { monitor.Active = wmiMonitorIdMo.GetProperty("Active"); monitor.ProductCodeID = GetStringFromArray(wmiMonitorIdMo.GetArrayProperty("ProductCodeID")); - if (wmiMonitorIdMo.TryGetArrayProperty("UserFriendlyName", out var userFriendlyNameUint16, - out _)) - { - monitor.UserFriendlyName = GetStringFromArray(userFriendlyNameUint16); - } else if (wmiMonitorIdMo.TryGetArrayProperty("UserFriendlyName", out var userFriendlyNameInt4, - out var errorReason)) - { - monitor.UserFriendlyName = GetStringFromArray(userFriendlyNameInt4); - } - else - { - WmiSearchResultItem.HandleArrayPropertyError("UserFriendlyName", errorReason); - } + // if (wmiMonitorIdMo.TryGetArrayProperty("UserFriendlyName", out var userFriendlyNameUint16, + // out _)) + // { + // monitor.UserFriendlyName = GetStringFromArray(userFriendlyNameUint16); + // } else if (wmiMonitorIdMo.TryGetArrayProperty("UserFriendlyName", out var userFriendlyNameInt4, + // out var errorReason)) + // { + // monitor.UserFriendlyName = GetStringFromArray(userFriendlyNameInt4); + // } + // else + // { + // WmiSearchResultItem.HandleArrayPropertyError("UserFriendlyName", errorReason); + // } monitor.UserFriendlyName = GetStringFromArray(wmiMonitorIdMo.GetArrayProperty("UserFriendlyName")); monitor.SerialNumberID = GetStringFromArray(wmiMonitorIdMo.GetArrayProperty("SerialNumberID")); monitor.ManufacturerName = GetStringFromArray(wmiMonitorIdMo.GetArrayProperty("ManufacturerName")); From 2deb65ccf22945fd2afe7966d0697433408c83ec Mon Sep 17 00:00:00 2001 From: Gitii Date: Thu, 3 Oct 2024 13:33:59 +0200 Subject: [PATCH 46/56] . --- .../PlatformHardwareInfo.cs | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs b/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs index c4dce71..5b128c1 100644 --- a/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs +++ b/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs @@ -565,20 +565,19 @@ public List GetMonitorList() { monitor.Active = wmiMonitorIdMo.GetProperty("Active"); monitor.ProductCodeID = GetStringFromArray(wmiMonitorIdMo.GetArrayProperty("ProductCodeID")); - // if (wmiMonitorIdMo.TryGetArrayProperty("UserFriendlyName", out var userFriendlyNameUint16, - // out _)) - // { - // monitor.UserFriendlyName = GetStringFromArray(userFriendlyNameUint16); - // } else if (wmiMonitorIdMo.TryGetArrayProperty("UserFriendlyName", out var userFriendlyNameInt4, - // out var errorReason)) - // { - // monitor.UserFriendlyName = GetStringFromArray(userFriendlyNameInt4); - // } - // else - // { - // WmiSearchResultItem.HandleArrayPropertyError("UserFriendlyName", errorReason); - // } - monitor.UserFriendlyName = GetStringFromArray(wmiMonitorIdMo.GetArrayProperty("UserFriendlyName")); + if (wmiMonitorIdMo.TryGetArrayProperty("UserFriendlyName", out var userFriendlyNameUint16, + out _)) + { + monitor.UserFriendlyName = GetStringFromArray(userFriendlyNameUint16); + } else if (wmiMonitorIdMo.TryGetArrayProperty("UserFriendlyName", out var userFriendlyNameInt4, + out var errorReason)) + { + monitor.UserFriendlyName = GetStringFromArray(userFriendlyNameInt4); + } + else + { + WmiSearchResultItem.HandleArrayPropertyError("UserFriendlyName", errorReason); + } monitor.SerialNumberID = GetStringFromArray(wmiMonitorIdMo.GetArrayProperty("SerialNumberID")); monitor.ManufacturerName = GetStringFromArray(wmiMonitorIdMo.GetArrayProperty("ManufacturerName")); monitor.WeekOfManufacture = (ushort) wmiMonitorIdMo.GetProperty("WeekOfManufacture"); From 97857d3c1439cce0acfbb9724a72cef29183bec9 Mon Sep 17 00:00:00 2001 From: Gitii Date: Thu, 3 Oct 2024 13:55:09 +0200 Subject: [PATCH 47/56] . --- Hardware.Info.Aot.Windows/Hardware.Info.Aot.Windows.csproj | 1 + Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Hardware.Info.Aot.Windows/Hardware.Info.Aot.Windows.csproj b/Hardware.Info.Aot.Windows/Hardware.Info.Aot.Windows.csproj index 3965137..349ab33 100644 --- a/Hardware.Info.Aot.Windows/Hardware.Info.Aot.Windows.csproj +++ b/Hardware.Info.Aot.Windows/Hardware.Info.Aot.Windows.csproj @@ -4,6 +4,7 @@ net8.0 enable enable + preview true true diff --git a/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs b/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs index be4baad..1536601 100644 --- a/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs +++ b/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs @@ -83,7 +83,6 @@ out pLoc if (hr.Failed) { - Console.WriteLine($"Could not set proxy blanket. Error code = 0x{hr:X}"); pSvc->Release(); pLoc->Release(); PInvoke.CoUninitialize(); @@ -103,7 +102,6 @@ out pLoc if (hr.Failed) { - Console.WriteLine($"WMI query failed. Error code = 0x{hr:X}"); pSvc->Release(); pLoc->Release(); PInvoke.CoUninitialize(); @@ -122,8 +120,9 @@ public void Close() private void ReleaseUnmanagedResources() { + _queryString.Dispose(); + _strQueryLanguage.Dispose(); _managementScope.Dispose(); - _queryString.Dispose(); } private void Dispose(bool disposing) @@ -489,7 +488,7 @@ public void Dispose() } } - public unsafe ref struct WmiSearch + public unsafe ref struct WmiSearch: IDisposable { private IWbemServices* _wbemServices; private IWbemLocator* _wbemLocator; From 49bab476c1a08a318f5d9a9005a571f336b69bbc Mon Sep 17 00:00:00 2001 From: Gitii Date: Thu, 3 Oct 2024 13:58:41 +0200 Subject: [PATCH 48/56] . --- Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs b/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs index 5b128c1..30f1213 100644 --- a/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs +++ b/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs @@ -255,11 +255,11 @@ public List GetCpuList(bool includePercentProcessorTime = true, int millise { string queryString = UseAsteriskInWMI ? "SELECT * FROM Win32_PerfFormattedData_PerfOS_Processor WHERE Name != '_Total'" : "SELECT Name, PercentProcessorTime FROM Win32_PerfFormattedData_PerfOS_Processor WHERE Name != '_Total'"; - ManagementObjectSearcher percentProcessorTimeMOS = new ManagementObjectSearcher(_managementScope, queryString, _timeout); + using ManagementObjectSearcher percentProcessorTimeMOS = new ManagementObjectSearcher(_managementScope, queryString, _timeout); queryString = UseAsteriskInWMI ? "SELECT * FROM Win32_PerfFormattedData_PerfOS_Processor WHERE Name = '_Total'" : "SELECT PercentProcessorTime FROM Win32_PerfFormattedData_PerfOS_Processor WHERE Name = '_Total'"; - ManagementObjectSearcher totalPercentProcessorTimeMOS = new ManagementObjectSearcher(_managementScope, queryString, _timeout); + using ManagementObjectSearcher totalPercentProcessorTimeMOS = new ManagementObjectSearcher(_managementScope, queryString, _timeout); try { From 23fbeedb924210322ed88b3cb97ed259aa777f6b Mon Sep 17 00:00:00 2001 From: Gitii Date: Fri, 4 Oct 2024 11:41:14 +0200 Subject: [PATCH 49/56] better error and cleanup handling --- .../Hardware.Info.Aot.Windows.csproj | 1 - .../ManagementObjectSearcher.cs | 79 ++++++++++++------- .../PlatformHardwareInfo.cs | 2 +- .../WmiSearchException.cs | 11 +++ 4 files changed, 61 insertions(+), 32 deletions(-) create mode 100644 Hardware.Info.Aot.Windows/WmiSearchException.cs diff --git a/Hardware.Info.Aot.Windows/Hardware.Info.Aot.Windows.csproj b/Hardware.Info.Aot.Windows/Hardware.Info.Aot.Windows.csproj index 349ab33..3965137 100644 --- a/Hardware.Info.Aot.Windows/Hardware.Info.Aot.Windows.csproj +++ b/Hardware.Info.Aot.Windows/Hardware.Info.Aot.Windows.csproj @@ -4,7 +4,6 @@ net8.0 enable enable - preview true true diff --git a/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs b/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs index 1536601..d3266b2 100644 --- a/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs +++ b/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs @@ -11,8 +11,7 @@ namespace Hardware.Info.Aot.Windows { delegate HRESULT ExtractValueDelegate(in VARIANT variant, out T value); delegate HRESULT ExtractArrayValueDelegate(in VARIANT variant, Span value, out uint length); - - + class ManagementObjectSearcher : IDisposable { private readonly int _timeout; @@ -44,8 +43,8 @@ out pLoc if (hr.Failed) { PInvoke.CoUninitialize(); - hr.ThrowOnFailure(); - return WmiSearch.Null; + + throw new WmiSearchException(hr, "Could not create WBEM Locator."); } // Connect to WMI through the IWbemLocator::ConnectServer method @@ -66,7 +65,8 @@ out pLoc { pLoc->Release(); PInvoke.CoUninitialize(); - return WmiSearch.Null; + + throw new WmiSearchException(hr, "Could not connect to WMI through the WBEM Locator."); } // Set security levels on the proxy @@ -86,7 +86,8 @@ out pLoc pSvc->Release(); pLoc->Release(); PInvoke.CoUninitialize(); - return WmiSearch.Null; + + throw new WmiSearchException(hr, "Could not set the authentication information of the locator."); } // Perform WMI query to get the Win32_OperatingSystem class @@ -105,21 +106,18 @@ out pLoc pSvc->Release(); pLoc->Release(); PInvoke.CoUninitialize(); - return WmiSearch.Null; + + throw new WmiSearchException(hr, "Could not perform wmi query operation."); } return new WmiSearch( pSvc, pLoc, pEnumerator, _timeout); } - - public void Close() - { - PInvoke.CoUninitialize(); - } - - + private void ReleaseUnmanagedResources() { + PInvoke.CoUninitialize(); + _queryString.Dispose(); _strQueryLanguage.Dispose(); _managementScope.Dispose(); @@ -155,7 +153,7 @@ internal WmiSearchResultItem(IWbemClassObject* item) _item = item; } - public unsafe T GetProperty(string name, T defaultValue = default!) + public T GetProperty(string name, T defaultValue = default!) { VARIANT vtProp = new VARIANT(); @@ -457,6 +455,7 @@ public bool MoveNext() if (_isCurrentInUse) { + // dispose the previous search result before requesting the next one IWbemClassObject** current = (IWbemClassObject**)_currentArrayHandle.Pointer; current[0]->Release(); @@ -467,28 +466,27 @@ public bool MoveNext() var hr = _enumerator->Next(_timeout, 1, array, &uReturn); + if (hr.Failed) + { + // dispose pinned memory on error + _currentArrayHandle.Dispose(); + } + hr.ThrowOnFailure(); _isCurrentInUse = uReturn > 0; - return uReturn > 0; - } - - public void Dispose() - { - if (_isCurrentInUse) + if (!_isCurrentInUse) { - IWbemClassObject** current = (IWbemClassObject**)_currentArrayHandle.Pointer; - current[0]->Release(); - - _isCurrentInUse = false; + // dispose pinned memory when end of query + _currentArrayHandle.Dispose(); } - _currentArrayHandle.Dispose(); + return uReturn > 0; } } - public unsafe ref struct WmiSearch: IDisposable + public unsafe class WmiSearch: IDisposable { private IWbemServices* _wbemServices; private IWbemLocator* _wbemLocator; @@ -503,6 +501,13 @@ internal WmiSearch(IWbemServices* wbemServices, IWbemLocator* wbemLocator, IEnum _timeout = timeout; } + private WmiSearch() + { + _wbemServices = null; + _wbemLocator = null; + _wbemEnumerator = null; + } + public WmiSearchResultsEnumerator GetEnumerator() { return new WmiSearchResultsEnumerator(_wbemEnumerator, _timeout); @@ -512,9 +517,23 @@ public WmiSearchResultsEnumerator GetEnumerator() public void Dispose() { - _wbemServices->Release(); - _wbemLocator->Release(); - _wbemEnumerator->Release(); + if (_wbemServices != null) + { + _wbemServices->Release(); + _wbemServices = null; + } + + if (_wbemLocator != null) + { + _wbemLocator->Release(); + _wbemLocator = null; + } + + if (_wbemEnumerator != null) + { + _wbemEnumerator->Release(); + _wbemEnumerator = null; + } } } } diff --git a/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs b/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs index 30f1213..69dce60 100644 --- a/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs +++ b/Hardware.Info.Aot.Windows/PlatformHardwareInfo.cs @@ -512,7 +512,7 @@ public List GetMemoryList() Manufacturer = mo.GetProperty("Manufacturer"), PartNumber = mo.GetProperty("PartNumber"), SerialNumber = mo.GetProperty("SerialNumber"), - Speed = mo.GetProperty("Speed") + Speed = mo.GetProperty("Speed") }; if (_os.Version.Major >= 10) diff --git a/Hardware.Info.Aot.Windows/WmiSearchException.cs b/Hardware.Info.Aot.Windows/WmiSearchException.cs new file mode 100644 index 0000000..86cd125 --- /dev/null +++ b/Hardware.Info.Aot.Windows/WmiSearchException.cs @@ -0,0 +1,11 @@ +using Windows.Win32.Foundation; + +namespace Hardware.Info.Aot.Windows; + +public class WmiSearchException: Exception +{ + internal WmiSearchException(HRESULT hResult, string message) : base(message) + { + this.HResult = hResult; + } +} \ No newline at end of file From b7a5cf0aa81dcc96fdbf89b894754b06ed94c9be Mon Sep 17 00:00:00 2001 From: Gitii Date: Sat, 5 Oct 2024 20:22:11 +0200 Subject: [PATCH 50/56] . --- Hardware.Info.Aot.Windows/WmiSearchException.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Hardware.Info.Aot.Windows/WmiSearchException.cs b/Hardware.Info.Aot.Windows/WmiSearchException.cs index 86cd125..88c967a 100644 --- a/Hardware.Info.Aot.Windows/WmiSearchException.cs +++ b/Hardware.Info.Aot.Windows/WmiSearchException.cs @@ -4,7 +4,7 @@ namespace Hardware.Info.Aot.Windows; public class WmiSearchException: Exception { - internal WmiSearchException(HRESULT hResult, string message) : base(message) + internal WmiSearchException(HRESULT hResult, string message) : base($"{message} ({hResult.Value:X})") { this.HResult = hResult; } From efcba4a8d592cb9a1ecde085a3b4c0eb4587ebf4 Mon Sep 17 00:00:00 2001 From: Gitii Date: Sat, 5 Oct 2024 20:33:51 +0200 Subject: [PATCH 51/56] . --- Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs b/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs index d3266b2..4abea04 100644 --- a/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs +++ b/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs @@ -31,9 +31,16 @@ public ManagementObjectSearcher(string managementScope, string queryString, int public unsafe WmiSearch Get() { + // Initialize COM + var hr = PInvoke.CoInitializeEx(null, COINIT.COINIT_MULTITHREADED); + if (hr.Failed) + { + throw new WmiSearchException(hr, "Failed to initialize COM library"); + } + // Obtain the initial locator to WMI IWbemLocator* pLoc; - var hr = PInvoke.CoCreateInstance( + hr = PInvoke.CoCreateInstance( CLSID_WbemLocator, (IUnknown*)0, CLSCTX.CLSCTX_INPROC_SERVER, From 1f626fba7ea632e14e9053b4aeb879239249f0c4 Mon Sep 17 00:00:00 2001 From: Gitii Date: Sat, 5 Oct 2024 20:36:21 +0200 Subject: [PATCH 52/56] . --- Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs b/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs index 4abea04..6901a95 100644 --- a/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs +++ b/Hardware.Info.Aot.Windows/ManagementObjectSearcher.cs @@ -31,6 +31,13 @@ public ManagementObjectSearcher(string managementScope, string queryString, int public unsafe WmiSearch Get() { + // See https://github.com/microsoft/windows-rs/issues/1169#issuecomment-925107412 + // for some remarks regarding CoInitializeEx & CoUninitialize. + // Important quote from that thread: + // Additional calls to CoInitialize paired with CoUninitialize are fine (and sometimes necessary when an + // STA is required) because they will simply act as additional references to the COM runtime and not + // cause the reference count to hit zero and begin unloading DLLs. + // Initialize COM var hr = PInvoke.CoInitializeEx(null, COINIT.COINIT_MULTITHREADED); if (hr.Failed) From e7b19ad90e0dd32afc73482ae3fd7953905233c5 Mon Sep 17 00:00:00 2001 From: Gitii Date: Sat, 5 Oct 2024 20:58:41 +0200 Subject: [PATCH 53/56] . --- Hardware.Info.Windows/Hardware.Info.Windows.csproj | 1 - Hardware.Info/Hardware.Info.csproj | 8 ++++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Hardware.Info.Windows/Hardware.Info.Windows.csproj b/Hardware.Info.Windows/Hardware.Info.Windows.csproj index 869ea67..cad8e6e 100644 --- a/Hardware.Info.Windows/Hardware.Info.Windows.csproj +++ b/Hardware.Info.Windows/Hardware.Info.Windows.csproj @@ -12,7 +12,6 @@ - diff --git a/Hardware.Info/Hardware.Info.csproj b/Hardware.Info/Hardware.Info.csproj index 261d48b..53dce8e 100644 --- a/Hardware.Info/Hardware.Info.csproj +++ b/Hardware.Info/Hardware.Info.csproj @@ -47,4 +47,12 @@ + + + + + + + + From 855ab35add6e6f885ca6c342ba45699c93958cff Mon Sep 17 00:00:00 2001 From: Gitii Date: Sat, 5 Oct 2024 21:09:09 +0200 Subject: [PATCH 54/56] . --- .github/workflows/tests.yml | 7 +------ build.sh | 5 ++++- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 816860b..867b5ac 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -6,7 +6,7 @@ on: - main pull_request: branches: - - main + - * workflow_dispatch: inputs: version: @@ -174,8 +174,3 @@ jobs: --no-readline | tee ./output.aot env: PUBLISH_DIR: ${{ steps.knownVariables.outputs.publishDirectory }} - - - name: Verify that output is identical - if: ${{ false }} - shell: bash - run: diff ./output.jit ./output.aot \ No newline at end of file diff --git a/build.sh b/build.sh index c0c74aa..2e78ba5 100644 --- a/build.sh +++ b/build.sh @@ -74,4 +74,7 @@ dotnet pack --no-restore \ -p:Version="$VERSION" \ -p:PackageVersion="$VERSION" \ -p:TargetFrameworks="$TFM" \ - -o ./dist \ No newline at end of file + -o ./dist + +echo "List of created artifacts:" +ll ./dist/* \ No newline at end of file From a92e026807a90755e5bea963b82eb3fa4d28c447 Mon Sep 17 00:00:00 2001 From: Gitii Date: Sat, 5 Oct 2024 21:11:23 +0200 Subject: [PATCH 55/56] . --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 867b5ac..350afdc 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -6,7 +6,7 @@ on: - main pull_request: branches: - - * + - '*' workflow_dispatch: inputs: version: From 7ac5ccc8e9cb1072acdfc91032903a458e056450 Mon Sep 17 00:00:00 2001 From: Gitii Date: Sat, 5 Oct 2024 21:13:13 +0200 Subject: [PATCH 56/56] . --- build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sh b/build.sh index 2e78ba5..9a855b1 100644 --- a/build.sh +++ b/build.sh @@ -77,4 +77,4 @@ dotnet pack --no-restore \ -o ./dist echo "List of created artifacts:" -ll ./dist/* \ No newline at end of file +ls -al ./dist/* \ No newline at end of file