【问题标题】:System Info from Universal Windows Platform or .NET Standard 2.0 class Library来自通用 Windows 平台或 .NET Standard 2.0 类库的系统信息
【发布时间】:2018-12-17 16:08:18
【问题描述】:

我正在为实用程序逻辑开发一个带有 .NET Standard 类库的 UWP 应用程序。 在这个应用程序中,我需要收集一些与操作 PC 相关的元数据

我想出了以下结构来读取数据

 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;
        }

我尝试如下获取主板 ID

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 应用的本地 PC 获取上述所有属性。

还尝试了类似下面的 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”一词未被识别为 cmdlet 的名称, 函数、脚本文件或可运行的程序。检查拼写 名称,或者如果包含路径,请验证路径是否正确并 再试一次。

更新


关注了这篇文章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)'。

任何帮助我都非常感谢。

【问题讨论】:

    标签: powershell uwp .net-standard-2.0


    【解决方案1】:

    我根据来自 microsoft toolkit SystemInformation helper 的数据、来自NetworkInformation 类的主机名、来自TimeZone.CurrentTimeZone 的时区和来自HomeGeographicRegion 的 SystemLocale 填充了您的开关

    我没有填写 TotalPhysicalMemory 因为在 UWP 中你无法获取系统 RAM 信息,因为它是沙盒。但是你可以从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;
    }
    

    【讨论】:

    • 感谢@Vignesh,仍在努力获取 SerialNumber 和 ProductId。序列号通过Powershell脚本get-ciminstance win32_bios |通过键入 systeminfo 从命令提示符格式化列表序列号和 ProductID。
    • UWP 有一些系统级 api 的限制。如果你真的需要访问这些,你可以创建一个 [appservice][1] 来运行一个小的 wpf sn-p 并将数据获取到 UWP 应用程序。 [1]:github.com/Microsoft/DesktopBridgeToUWP-Samples/tree/master/…
    猜你喜欢
    • 2019-04-21
    • 2010-10-13
    • 1970-01-01
    • 2018-06-23
    • 2015-03-21
    • 2012-05-18
    • 2018-03-14
    • 2018-02-08
    • 2018-04-27
    相关资源
    最近更新 更多