diff --git a/src/DeviceId/Components/MacosProcessorIdDeviceIdComponent.cs b/src/DeviceId/Components/MacosProcessorIdDeviceIdComponent.cs
new file mode 100644
index 0000000..38ecb68
--- /dev/null
+++ b/src/DeviceId/Components/MacosProcessorIdDeviceIdComponent.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Text;
+using DeviceId.CommandExecutors;
+using DeviceId.Internal;
+
+namespace DeviceId.Components
+{
+ ///
+ /// An implementation of that uses the root drive's serial number.
+ ///
+ public class MacosProcessorIdDeviceIdComponent
+ : IDeviceIdComponent
+ {
+ ///
+ /// Gets the name of the component.
+ ///
+ public string Name { get; } = "ProcessorId";
+
+ ///
+ /// Command executor.
+ ///
+ private readonly ICommandExecutor _commandExecutor;
+
+ ///
+ /// Should the contents of the file be hashed? (Relevant for sources such as /proc/cpuinfo)
+ ///
+ private readonly bool _shouldHashContents;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MacosProcessorIdDeviceIdComponent(bool shouldHashContents = false)
+ : this(CommandExecutor.Bash, shouldHashContents) { }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The command executor to use.
+ /// Whether the result contents should be hashed
+ internal MacosProcessorIdDeviceIdComponent(ICommandExecutor commandExecutor, bool shouldHashContents = false)
+ {
+ _commandExecutor = commandExecutor;
+ _shouldHashContents = shouldHashContents;
+ }
+
+ ///
+ /// Gets the component value.
+ ///
+ /// The component value.
+ public string GetValue()
+ {
+ var contents = _commandExecutor.Execute("sysctl -a | grep machdep.cpu");
+
+ if (!string.IsNullOrEmpty(contents))
+ {
+ if (!_shouldHashContents)
+ {
+ return contents;
+ }
+
+ using var hasher = MD5.Create();
+ var hash = hasher.ComputeHash(Encoding.ASCII.GetBytes(contents));
+ return BitConverter.ToString(hash).Replace("-", "").ToUpper();
+ }
+
+ return null;
+ }
+
+ }
+}
diff --git a/src/DeviceId/DeviceIdBuilderExtensions.cs b/src/DeviceId/DeviceIdBuilderExtensions.cs
index 4ca2c98..ca58032 100644
--- a/src/DeviceId/DeviceIdBuilderExtensions.cs
+++ b/src/DeviceId/DeviceIdBuilderExtensions.cs
@@ -90,6 +90,10 @@ public static DeviceIdBuilder AddProcessorId(this DeviceIdBuilder builder)
{
return builder.AddComponent(new FileDeviceIdComponent("ProcessorId", "/proc/cpuinfo", true));
}
+ else if (OS.IsOSX)
+ {
+ return builder.AddComponent(new MacosProcessorIdDeviceIdComponent(true));
+ }
else
{
return builder.AddComponent(new UnsupportedDeviceIdComponent("ProcessorId"));
@@ -111,6 +115,13 @@ public static DeviceIdBuilder AddMotherboardSerialNumber(this DeviceIdBuilder bu
{
return builder.AddComponent(new FileDeviceIdComponent("MotherboardSerialNumber", "/sys/class/dmi/id/board_serial"));
}
+ else if (OS.IsOSX)
+ {
+ return builder.AddComponent(new CommandComponent(
+ name: "MotherboardSerialNumber",
+ command: "ioreg -d2 -c IOPlatformExpertDevice | awk -F\" '/board-id/{print $(NF-1)}'",
+ commandExecutor: CommandExecutor.Bash));
+ }
else
{
return builder.AddComponent(new UnsupportedDeviceIdComponent("MotherboardSerialNumber"));
@@ -160,6 +171,13 @@ public static DeviceIdBuilder AddSystemUUID(this DeviceIdBuilder builder)
{
return builder.AddComponent(new FileDeviceIdComponent("SystemUUID", "/sys/class/dmi/id/product_uuid"));
}
+ else if (OS.IsOSX)
+ {
+ return builder.AddComponent(new CommandComponent(
+ name: "SystemUUID",
+ command: "ioreg -d2 -c IOPlatformExpertDevice | awk -F\" '/IOPlatformUUID/{print $(NF-1)}'",
+ commandExecutor: CommandExecutor.Bash));
+ }
else
{
return builder.AddComponent(new UnsupportedDeviceIdComponent("SystemUUID"));