Вопрос
Какими способами я могу запросить спецификации локального компьютера (различные данные, начиная со спецификаций процессора, версии операционной системы, спецификаций видеокарты и драйверов и т.д.) Через программный интерфейс?Мы пишем простое приложение на C # для тестирования совместимости нашего основного приложения и хотим, чтобы оно выводило некоторые системные показатели, но, похоже, я не могу найти, с чего хотя бы начать, какие интерфейсы использовать, библиотеки, что угодно.
Я перепробовал все виды поиска, но смог найти только программы, причем с графическим интерфейсом, для взаимодействия с которыми требуется пользователь или которые необходимо установить.
В качестве альтернативы, небольшая программа из командной строки работала бы так же хорошо, если бы нам было разрешено распространять ее вместе с тестовым приложением.
Я нашел одну программу, которая получает некоторые из тех спецификаций, которые мне нужны, PsInfo.Однако, похоже, требуется, чтобы каждый пользователь соглашался с некоторой лицензией при первом запуске, даже если это приложение командной строки.Кроме того, он имеет дело только с информацией об операционной системе / процессоре, и мне понадобится нечто большее.
Также:забыл упомянуть явно, но это действительно будет необходимо только для компьютеров с Windows.Вы, ребята, быстро соображаете!
Редактировать:Этот WMI действительно выглядит так, как мне нужно, спасибо!Правда, целая банка червей, так что мне придется нырнуть в нее.В нем упоминается, что для некоторых вещей пользователь должен иметь права администратора;вероятно, это не будет большой проблемой, но может немного ограничить ее.
Решение
Для получения такого рода информации WMI это твой друг.К счастью, работать с WMI в .NET намного проще, чем в неуправляемом мире.Существует довольно много статей, с которых можно начать, например этот, или этот для получения информации о процессоре.
В конечном итоге вы будете писать SQL-подобные запросы к объектам в пространстве имен WMI для извлечения нужной вам информации.
Другие советы
Может быть, стоит подумать об использовании Инструментарий управления Windows (WMI), предполагая, что вы планируете запросить компьютер с Windows.Взгляните на Создатель кода WMI от Microsoft.Это может легко помочь вам ознакомиться с примерами кода на нескольких языках.
WMI отлично работает вплоть до эпохи Windows 2000, но с некоторой помощью может работать и на компьютерах с Win98.
До тех пор, пока у вас есть или вы можете предоставить учетные данные администратора для компьютера, к которому вы пытаетесь запросить, WMI - это, безусловно, правильный путь.
С таким же успехом я мог бы опубликовать базовый код, который я использовал, чтобы получить все, что мне было нужно, используя WMI, как было предложено здесь.
Нужно включить ссылку на System.Management в проект c #.Кроме того, сам исходный код, вероятно, ужасно оформленный на c #, но я никогда раньше на нем не писал, и он предназначен для внутреннего инструмента, так что это как бы не суть важно.Я немного упростил его, так что на самом деле он имеет дело только с выводом спецификаций машины (инструмент выполняет и другие функции помимо этого).Каждый вызов LogClass() удаляет все его свойства.Для получения дополнительных классов для выгрузки, просто ознакомьтесь с разделом MSDN на Классы WMI.
using System;
using System.Collections.Generic;
using System.Text;
using System.Management;
using System.IO;
namespace SyTest
{
class Program
{
static StreamWriter specStream;
static void Main(string[] args)
{
FileStream specFile =
new FileStream("machine-specs.txt",FileMode.Create,FileAccess.Write);
specStream = new StreamWriter(specFile);
LogClass("Win32_DesktopMonitor");
LogClass("Win32_VideoController");
LogClass("Win32_Processor");
// etc
specStream.Close();
specFile.Close();
}
static void LogClass(string strTable)
{
if (strTable.Length <= 0) return;
specStream.Write("--- " + strTable + " ---\r\n\r\n");
WqlObjectQuery wqlQuery =
new WqlObjectQuery("SELECT * FROM " + strTable);
ManagementObjectSearcher searcher =
new ManagementObjectSearcher(wqlQuery);
try
{
if (searcher.Get().Count <= 0)
{
specStream.Write("Class has no instances\r\n\r\n");
}
foreach (ManagementObject obj in searcher.Get())
{
specStream.Write("* " + obj.ToString() + "\r\n");
if (obj.Properties.Count <= 0)
{
specStream.Write("Class instance has no properties\r\n");
continue;
}
foreach (System.Management.PropertyData prop in obj.Properties)
{
LogAttr(obj, prop.Name);
}
specStream.Write("\r\n");
}
}
catch { specStream.Write("Class does not exist\r\n\r\n"); }
}
static void LogAttr(ManagementObject obj, string str)
{
if (str.Length <= 0) return;
string strValue = "";
try
{
strValue = obj[str].ToString();
try
{
string[] pstrTmp = ((string[])obj[str]);
if (pstrTmp.Length > 0) strValue = String.Join(", ", pstrTmp);
}
catch { } // Problem casting, fall back on original assignment
}
catch { strValue = "[UNDEFINED]"; }
specStream.Write(str + ": " + strValue + "\r\n");
}
}
}
Для странного случая, который вы разрабатывали бы для linux, вы могли бы найти потрясающие материалы внутри /proc
псевдофайловая система.
Если вы решите использовать WMI, возможно, вам захочется ознакомиться с Создатель кода WMI от Microsoft.Это довольно упрощает работу с WMI.
Существует пакет nuget, который называется MissingLinq.Linq2Management
это превратило практически все, что касается WMI, в приятный строго типизированный объект.Кажется довольно милым.