Информация о системе из универсальной платформы Windows или библиотеки классов .NET Standard 2.0 - PullRequest
0 голосов
/ 17 декабря 2018

Я занимаюсь разработкой приложения UWP с библиотекой классов .NET Standard для логики утилит.В этом приложении мне нужно собрать некоторые метаданные, связанные с работой ПК

. Я создал следующую структуру для чтения данных

 public static void LoadSystemInfo(this Payload payload)
        {
            payload.SystemInfo = new SystemInfo
            {
                Machine = new Machine
                {
                    SerialNumber = SystemInfo("SerialNumber"),
                    UuId = SystemInfo("UuId"),
                },
                HostName = SystemInfo("HostName"),
                OsVersion = SystemInfo("OsVersion"),
                OsManufacturer = SystemInfo("OsManufacturer"),
                DeviceId = SystemInfo("DeviceId"),
                SystemManufacturer = SystemInfo("SystemManufacturer"),
                SystemModel = SystemInfo("SystemModel"),
                SystemType = SystemInfo("SystemType"),
                SystemLocale = SystemInfo("SystemLocale"),
                TimeZone = SystemInfo("TimeZone"),
                TotalPhysicalMemory = SystemInfo("TotalPhysicalMemory"),
                AvailablePhysicalMemory = SystemInfo("AvailablePhysicalMemory"),
            };
        }
        private static string  SystemInfo(string key)
        {
            switch (key)
            {
                case "SerialNumber":
                    return GetMotherBoardId();
                case "UuId":
                    return "";
                case "HostName":
                    return "";
                case "OsVersion":
                    return "";
                case "OsManufacturer":
                    return "";
                case "DeviceId":
                    return "";
                case "SystemManufacturer":
                    return "";
                case "SystemModel":
                    return "";
                case "SystemType":
                    return "";
                case "SystemLocale":
                    return "";
                case "TimeZone":
                    return "";
                case "TotalPhysicalMemory":
                    break;
                case "AvailablePhysicalMemory":
                    return "";
                default:
                    return $"Missing Case for {key}";
            }
            return null;
        }

Я пытался получить идентификатор материнской платы, как показано ниже

public static string GetMotherBoardId()
        {
            string mbInfo = string.Empty;
            ManagementScope scope = new ManagementScope("\\\\" + Environment.MachineName + "\\root\\cimv2");
            scope.Connect();
            ManagementObject wmiClass = new ManagementObject(scope,
                new ManagementPath("Win32_BaseBoard.Tag=\"Base Board\""), new ObjectGetOptions());

            foreach (PropertyData propData in wmiClass.Properties)
            {
                if (propData.Name == "SerialNumber")
                    mbInfo = $"{propData.Name,-25}{Convert.ToString(propData.Value)}";
            }

            return mbInfo;
        }

Это выдает ошибку как System.Management в настоящее время поддерживается только для настольных приложений Windows.

Как получить все перечисленные выше свойства с локального ПК, который работаетмое приложение UWP.

Также пробовал скрипт PowerShell, как показано ниже

using (PowerShell powerShellInstance = PowerShell.Create())
                    {
                        powerShellInstance.AddCommand("get-wmiobject");
                        powerShellInstance.AddParameter("class", "Win32_ComputerSystemProduct");
                        //powerShellInstance.AddScript(
                        //    "get-wmiobject Win32_ComputerSystemProduct | Select-Object -ExpandProperty UUID");
                        Collection<PSObject> psOutput = powerShellInstance.Invoke();

                    }

, который выдает ошибку, как показано ниже

Термин «get-wmiobject» не распознается какимя командлета, функции, файла сценария или работающей программы.Проверьте правильность написания имени или, если путь был указан, проверьте правильность пути и повторите попытку.

Обновление


Соблюдаетсяэта статья https://docs.microsoft.com/en-us/windows/desktop/wmisdk/retrieving-an-instance и она все еще не работает

string Namespace = @"root\cimv2";
string className = "Win32_LogicalDisk";

CimInstance myDrive = new CimInstance(className, Namespace);
CimSession mySession = CimSession.Create("localhost");
CimInstance searchInstance = mySession.GetInstance(Namespace, myDrive);

Выдает следующее сообщение об ошибке

Доступ к ресурсу CIM не был доступен для клиента.

Когда я пытаюсь это сделать

  ManagementObjectSearcher mgmtObjSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_LogicalDisk");
                    ManagementObjectCollection colDisks = mgmtObjSearcher.Get();

Я получаю эту ошибку

System.Management в настоящее время поддерживается только для настольных приложений Windows.

Когда я пытаюсь это

string command = "Get-Command Write-Output";
                    using (var ps = PowerShell.Create())
                    {
                        var results = ps.AddScript(command).Invoke();
                        foreach (var result in results)
                        {
                           Console.WriteLine(result.ToString());
                        }
                        ps.Commands.Clear();
                    }

Я получаю эту ошибку

Произошла ошибка при создании конвейера.-> Метод не найден: 'System.Text.StringBuilder System.Text.StringBuilder.Append (System.Text.StringBuilder)'.

Любая помощь, которую я очень ценю.

1 Ответ

0 голосов
/ 17 декабря 2018

Я заполнил ваш переключатель на основе данных из набора инструментов Microsoft SystemInformation помощник, имя хоста из NetworkInformation класса, часовой пояс от TimeZone.CurrentTimeZone и SystemLocaleот HomeGeographicRegion

Я не заполнил TotalPhysicalMemory, потому что в UWP вы не можете получить информацию об оперативной памяти системы, так как это песочница.Но вы можете получить лимит использования памяти приложения от MemoryManager

Для SerialNumber вы можете использовать SystemIdentification.GetSystemIdForPublisher(), получит необработанные данные в виде буфера, который вы можете обработать.

private static string SystemInfo(string key)
{
   EasClientDeviceInformation deviceInfo = new EasClientDeviceInformation();
   switch (key)
   {
     case "SerialNumber":
        break ;
     case "UuId":
        return deviceInfo.Id.ToString();
     case "HostName":
        var hostNames = NetworkInformation.GetHostNames();
        return  hostNames.FirstOrDefault(name => name.Type == HostNameType.DomainName)?.DisplayName ?? "???";                     
     case "OsVersion":
        ulong version = ulong.Parse(AnalyticsInfo.VersionInfo.DeviceFamilyVersion);
        return  ((version & 0xFFFF000000000000L) >> 48).ToString()+"."+
          ((version & 0x0000FFFF00000000L) >> 32).ToString()+"."+((version & 0x00000000FFFF0000L) >> 16).ToString()+"."+(version & 0x000000000000FFFFL).ToString();
     case "OsManufacturer":
        return deviceInfo.OperatingSystem;
     case "DeviceId":
        return "";
     case "SystemManufacturer":
        return deviceInfo.SystemManufacturer; 
     case "SystemModel":
        return deviceInfo.SystemProductName;
     case "SystemType":
        return Package.Current.Id.Architecture.ToString();
     case "SystemLocale":
        return Windows.System.UserProfile.GlobalizationPreferences.HomeGeographicRegion;
     case "TimeZone":
        return TimeZone.CurrentTimeZone.StandardName.ToString();
     case "TotalPhysicalMemory":
        break;
     case "AvailablePhysicalMemory":
        return ((float)MemoryManager.AppMemoryUsageLimit / 1024 / 1024).ToString();
     default:
        return $"Missing Case for {key}";
    }
  return null;
}
...