Как я могу проверить, запущен ли определенный процесс на удаленном ПК/сервере?

string ComputerName = serverName;
ManagementScope Scope;

if (!ComputerName.Equals("localhost", StringComparison.OrdinalIgnoreCase))
{
    ConnectionOptions Conn = new ConnectionOptions();
    Conn.Username = "";
    Conn.Password = "";
    Conn.Authority = "ntlmdomain:DOMAIN";
    Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", ComputerName), Conn);
}
else
    Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", ComputerName), null);

Scope.Connect(); // CRASH HERE
ObjectQuery Query = new ObjectQuery("SELECT * FROM Win32_Process Where Name='" + processName + "'");
ManagementObjectSearcher Searcher = new ManagementObjectSearcher(Scope, Query);

Появляется сообщение:

Значение не попадает в ожидаемый диапазон.


person software is fun    schedule 14.12.2015    source источник
comment
Верны ли учетные данные? Почему вы добавляете null в качестве параметра в конструкторе в предложении else? Согласно msdn.microsoft. com/de-de/library/ , вы можете просто не указывать его. Кроме того, можете ли вы дать более подробную трассировку стека, где именно во внутренней функции происходит сбой?   -  person Maximilian Gerhardt    schedule 14.12.2015
comment
Сбой в Scope.Connect (я прокомментировал это в коде)   -  person software is fun    schedule 14.12.2015


Ответы (1)


Скорее всего, это связано с неправильными учетными данными или недостаточными разрешениями. В вашем случае имя пользователя не указано - я уверен, что вы не можете передать пустое имя пользователя. Имя пользователя/пароль, которые вы используете для запроса WMI, должны существовать на удаленном ПК (плюс пользователь должен иметь достаточные разрешения).

Если вы хотите использовать то же имя пользователя/пароль, с которым вы вошли в систему на локальном ПК (с которого вы запускаете код), вы должны опустить всю часть ConnectionOptions:

    //ConnectionOptions Conn = new ConnectionOptions();
    //Conn.Username = "";
    //Conn.Password = "";
    //Conn.Authority = "ntlmdomain:DOMAIN";

Я попробовал ваш код (добавил последние 4 строки для тестирования) и получил ту же ошибку, что и у вас. Как только я добавил имя пользователя и пароль, все работает нормально.

string ComputerName = "10.1.2.3";
ManagementScope Scope;

if (!ComputerName.Equals("localhost", StringComparison.OrdinalIgnoreCase))
{
    ConnectionOptions Conn = new ConnectionOptions();
    Conn.Username = "Administrator";
    Conn.Password = "pass123";
    //Conn.Authority = "ntlmdomain:DOMAIN";
    Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", ComputerName), Conn);
}
else
    Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", ComputerName), null);

Scope.Connect(); // CRASH HERE
ObjectQuery Query = new ObjectQuery("SELECT * FROM Win32_Process Where Name='" + "cmd.exe" + "'");
ManagementObjectSearcher Searcher = new ManagementObjectSearcher(Scope, Query);

ManagementObjectCollection queryCollection = Searcher.Get();

foreach (var item in queryCollection)
    Console.WriteLine(item["Description"]);

Console.Read();

Я также попробовал тот же код с закомментированным разделом, касающимся ConnectionOptions, и он также работает. Обратите внимание, однако, что, согласно тому, что я писал ранее, мне пришлось создать пользователя на удаленном ПК, который имеет те же учетные данные, что и пользователь, под которым я вошел в систему на локальном ПК.

Надеюсь это поможет.

РЕДАКТИРОВАТЬ: Также согласно комментарию Максимилиана Герхардта, пропустите NULL эту строку:

Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", ComputerName), null);
person callmebob    schedule 18.12.2015