Ziba Leah
Ziba Leah

Reputation: 2514

Xamarin Mac - Get System Information Programmatically

I'm trying to get the basic system information in Xamarin Mac Programmatically.

The info I need is:

And so on. I checked a couple of articles but in many cases all the info I get are OS Related more than HW related.

eg: https://forums.xamarin.com/discussion/21835/get-system-information

eg: NSDictionary setting = NSDictionary.FromFile ("/System/Library/CoreServices/SystemVersion.plist");  
string os_version_string = (NSString)setting.ValueForKey ((NSString)"ProductVersion");

Thanks in advance

Upvotes: 0

Views: 538

Answers (1)

Cheesebaron
Cheesebaron

Reputation: 24470

You can get most of this information by querying sysctl. However, this isn't exposed in the Darwin class so you need to do a little bit of DllImport yourself.

[DllImport(Constants.SystemLibrary)]
internal static extern int sysctlbyname(
    [MarshalAs(UnmanagedType.LPStr)] string property,
    IntPtr output,
    IntPtr oldLen,
    IntPtr newp,
    uint newlen);

Then you can get values with:

public static string GetSystemProperty(string property)
{
    var pLen = Marshal.AllocHGlobal(sizeof(int));
    sysctlbyname(property, IntPtr.Zero, pLen, IntPtr.Zero, 0);
    var length = Marshal.ReadInt32(pLen);
    var pStr = Marshal.AllocHGlobal(length);
    sysctlbyname(property, pStr, pLen, IntPtr.Zero, 0);
    return Marshal.PtrToStringAnsi(pStr);
 }

You can list all keys on your machine by running sysctl -a in a command line to figure out what to query. So for the information you are looking for you want to do:

var cpu = GetSystemProperty("machdep.cpu.brand_string");
var ram = GetSystemProperty("hw.memsize");
var macModel = GetSystemProperty("hw.model");
var osVersion = GetSystemProperty("kern.osrelease");
var hostName = GetSystemProperty("kern.hostname");

You can get screen information with:

var screenSize = $"{NSScreen.MainScreen.Frame.Width}x{NSScreen.MainScreen.Frame.Height}";

EDIT:

You can get the device serial by querying the IOKit IOPlatformExpertDevice. This code might also work on iOS:

public static class DeviceSerial
{
    [DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
    private static extern uint IOServiceGetMatchingService(uint masterPort, IntPtr matching);

    [DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
    private static extern IntPtr IOServiceMatching(string s);

    [DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
    private static extern IntPtr IORegistryEntryCreateCFProperty(uint entry, IntPtr key, IntPtr allocator, uint options);

    [DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
    private static extern int IOObjectRelease(uint o);

    public static string GetSerial()
    {
        string serial = string.Empty;
        uint platformExpert = IOServiceGetMatchingService(0, IOServiceMatching("IOPlatformExpertDevice"));
        if (platformExpert != 0)
        {
            NSString key = (NSString)"IOPlatformSerialNumber";
            IntPtr serialNumber = IORegistryEntryCreateCFProperty(platformExpert, key.Handle, IntPtr.Zero, 0);
            if (serialNumber != IntPtr.Zero)
            {
                serial = NSString.FromHandle(serialNumber);
            }
            IOObjectRelease(platformExpert);
        }
        return serial;
    }
}

Then you can get the serial with:

var serial = DeviceSerial.GetSerial();

Upvotes: 2

Related Questions