#c# #wmi
#c# #wmi
Вопрос:
Я просмотрел десятки связанных вопросов SO и более сотни страниц MS Docs и до сих пор не могу найти то, чего мне не хватает. Моя конечная цель — создать список нескольких лучших потребителей ЦП и ОЗУ, когда общее использование ЦП или ОЗУ превышает пороговое значение. Получить общее число было относительно легко. Моя загадка — это препятствия, с которыми я сталкиваюсь при каждом подходе, который я пытаюсь использовать для сбора отдельных данных процесса.
Я сначала попробовал Process.GetProcesses()
, но половина процессов, которые он возвращает, генерирует исключения, когда я пытаюсь получить доступ к их свойствам использования ресурсов. (Это не так уж плохо, поскольку большинство из них меня не волнуют.) Я могу игнорировать их и использовать то, что работает, но я не могу полагаться на то, что игнорируемые процессы не входят в нужный мне набор.
Затем я углубился в WMI и протестировал скрипт VB, чтобы убедиться, что он может собирать информацию обо всех процессах:
Set objWMIService = GetObject("winmgmts:")
Set colProcesses = objWMIService.ExecQuery("Select * from Win32_Process")
For Each objProcess in colProcesses
sngProcessTime = (CSng(objProcess.KernelModeTime) CSng(objProcess.UserModeTime)) / 10000000
Wscript.Echo objProcess.Name amp; " CPU: " amp; sngProcessTime _
amp; " MEM: " amp; objProcess.WorkingSetSize/1024
Next
Это так. Номера памяти кажутся неправильными, но это препятствие может подождать. Возвращаясь к C #, я скопировал простой пример из MS Docs, в котором просто перечислены процессы:
using Microsoft.Management.Infrastructure;
. . .
{
var cimSession = CimSession.Create("localhost");
var enumeratedInstances = cimSession.EnumerateInstances(@"rootcimv2", "Win32_Process");
foreach (CimInstance cimInstance in enumeratedInstances)
Console.WriteLine("{0}", cimInstance.CimInstanceProperties["Name"].Value.ToString());
}
Я ссылался на Windows 10 SDK для библиотеки DLL MMI. Приложение успешно создает CIMSession
, но завершается ошибкой при EnumerateInstances
вызове метода с ошибкой «Клиент не может подключиться к месту назначения, указанному в запросе». Я не могу найти никаких указаний на то, чего может не хватать. Что это может быть???
Я не очень против того, чтобы написать какой-нибудь код Win32 C для получения этого, но я так давно не был на C , что забыл вдвое больше, чем помню. Если я должен пойти этим путем, я бы предпочел сделать это с помощью обернутых вызовов из C #.
(Все это на одном компьютере; удаленные компьютеры не задействованы.)
Комментарии:
1. Здесь полный выстрел в темноте, и я знаю его локальный хост, но работает ли ваш брандмауэр? Мне пришлось отключить брандмауэр Windows
tasklist.exe
, чтобы показать процессы, которые используют WMI.
Ответ №1:
Я считаю, что это то, чего вы хотите. Этот код вернет идентификатор процесса и его загрузку процессора. В показанном примере используется localhost. Здесь есть несколько ошибок. Если вы пытаетесь получить доступ к другому компьютеру в сети, вам необходимо убедиться, что брандмауэр и антивирусное программное обеспечение разрешают WMI / RPC. Также вам может потребоваться предоставить учетные данные для входа на этот компьютер. Те же ошибки применимы к сетевым доменам. Вам обязательно понадобятся учетные данные.
Вот документация Microsoft ManagementScope.
try
{
var scope = new ManagementScope($@"\localhostROOTCIMV2");
// If you're on a domain you will need to provide credentials
//
//var scope = new ManagementScope(
// $@"\{macheName}ROOTCIMV2",
//new ConnectionOptions
//{
// Username = "{Username}",
// Password = "{Password}"
//});
scope.Connect();
var query = new ObjectQuery("SELECT * FROM Win32_PerfFormattedData_PerfProc_Process");
var searcher = new ManagementObjectSearcher(scope, query);
var queryCollection = searcher.Get();
foreach (var m in queryCollection)
{
var pId = m["IDProcess"];
var cpuTime = m["PercentProcessorTime"];
}
}
catch
{
// ignored
}
Комментарии:
1. Большое спасибо!! Это меня намного ближе. К сожалению, значение для PercentProcessorTime равно нулю для всех процессов. Возможно, я смогу перейти отсюда к тому, что мне нужно.