Я разрабатываю приложение 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();
}
что дает ошибку, как показано ниже
The term 'get-wmiobject' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
Обновлять
Следил за этой статьей 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);
Выдает следующую ошибку
Access to a CIM resource was not available to the client.
Когда я пробую это
ManagementObjectSearcher mgmtObjSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_LogicalDisk");
ManagementObjectCollection colDisks = mgmtObjSearcher.Get();
Я получаю эту ошибку
System.Management currently is only supported for Windows desktop applications.
Когда я пробую это
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();
}
Я получаю эту ошибку
An error occurred while creating the pipeline. --> Method not found: 'System.Text.StringBuilder System.Text.StringBuilder.Append(System.Text.StringBuilder)'.
Любая помощь, которую я очень ценю.
Я заполнил ваш свитч на основе данных из помощника Microsoft Toolkit SystemInformation
, имени хоста из класса NetworkInformation
, часового пояса из TimeZone.CurrentTimeZone
и SystemLocale из HomeGeographicRegion
Я не заполнял 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;
}
UWP имеет некоторые ограничения api на системном уровне. Если вам действительно нужен доступ к ним, вы можете создать [appservice] [1] для запуска небольшого сниппета wpf и получения данных в приложение UWP. [1]: github.com/Microsoft/DesktopBridgeToUWP-Samples/tree/master/…
Спасибо @Vignesh, все еще не могу получить SerialNumber и ProductId. Серийный номер через сценарий Powershell get-ciminstance win32_bios | format-list серийный номер и ProductID из командной строки, набрав systeminfo.