Windows - перед запуском тестов проверьте, заблокирован ли компьютер - PullRequest
0 голосов
/ 22 апреля 2019

У меня есть набор тестов пользовательского интерфейса, которые я запускаю локально / удаленно в зависимости от ситуации. Иногда удаленные компьютеры автоматически перезагружаются всякий раз, когда необходимо применить важное обновление. Это приводит к тайм-ауту всех тестов, поскольку удаленные компьютеры, на которых они работают, заблокированы и больше не имеют доступа к графическому интерфейсу.

Мне интересно, как я могу быстро проверить, заблокирован ли компьютер, чтобы я мог быстро провалить тесты и зарегистрировать их в автономном режиме.

Я нашел это решение в Интернете, но, похоже, оно больше ориентировано на разработку, а не на тестирование.

https://bytes.com/topic/net/answers/770957-get-computer-state-locked-stand-c

Действительно просто нужен чистый способ проверить, заблокирован ли текущий компьютер или нет с использованием библиотек C #, и поместить его в метод, подобный приведенному ниже.

public bool IsWindowsLocked(){

     // Check if the current machine is in a locked state

}

1 Ответ

2 голосов
/ 24 апреля 2019

К сожалению, на самом деле нет никаких чистых способов сделать это, по крайней мере, я не смог бы найти, если только вы не захотите использовать что-то вроде query user с PsExec для удаленного выполнения этого на каждом ПК в качестве подпрограммы. обработать, а затем проанализировать результаты. Даже тогда, когда вы не получите прямого ответа о заблокированном состоянии, вам придется перейти в режим ожидания, так как Статус показывает, что один из пользователей активен, когда никто не использует компьютер.

Тогда существует проблема с несколькими пользователями, которые вошли в систему на компьютере, используя функциональность Switch User в Windows 7 или выше. В моей среде ПК может иметь 3 или 4 фоновых пользователя и одного пользователя консоли. В некоторых случаях ПК используются пользователями RDP. И оказывается, что есть особый случай, когда вы подключаетесь к компьютеру, а затем входите в консоль или делаете обратное, поскольку LogonSession LogonType в этих случаях не обновляется. К сожалению, также возможно поймать пользователя, только входящего в компьютер, и в этом случае моя функция неправильно скажет, что компьютер не используется.

На моем компьютере и в сети эта функция запускается примерно за 0,2 секунды, если компьютер включен. На некоторых ПК это может занять гораздо больше времени (до 20 секунд), поскольку на ПК загружается поставщик perfmon. Если компьютер выключен, время ожидания достаточно велико, и если это возможно, я бы рекомендовал сначала выполнить проверку пинга.

В основном функция использует WMI для получения информации LogonSession и Interactive Desktops, а Process для получения процессов LogonUI и проводника. Поскольку LogonSession возвращает старые сеансы, которые вышли из системы, и сеансы для программ администратора UAC и других (Windows 10) фоновых процессов (DWM / UMFD), мы учитываем только те сеансы LogonSession, которые имеют процесс explorer.exe (рабочий стол).

Затем объединяет информацию в разные случаи:

  1. Если число процессов LogonUI больше или равно количеству интерактивных рабочих столов, ПК либо вышел из системы, либо заблокирован. Если на ПК есть LogonSessions (с проводником), он блокируется, иначе он выходит из системы.

  2. Если число процессов LogonUI меньше количества интерактивных рабочих столов, значит, ПК используется.

Вот код:

enum PCUserStatuses {
    Locked, // all users are locked
    LoggedOff, // No users are logged in
    InUse, // A user is using this computer
    Unknown // unable to connect to computer / other error
}

PCUserStatuses GetPCUserStatus(string machineName) {
    try {
        var scope = GetManagementScope(machineName);
        scope.Connect();

        var explorerProcesses = Process.GetProcessesByName("explorer", machineName)
                                    .Select(p => p.Id.ToString())
                                    .ToHashSet();

        var REprocessid = new Regex(@"(?<=Handle="").*?(?="")", RegexOptions.Compiled);

        var numberOfLogonSessionsWithExplorer = new ManagementObjectSearcher(scope, new SelectQuery("SELECT * FROM Win32_SessionProcess")).Get()
                                                    .Cast<ManagementObject>()
                                                    .Where(mo => explorerProcesses.Contains(REprocessid.Match(mo["Dependent"].ToString()).Value))
                                                    .Select(mo => mo["Antecedent"].ToString())
                                                    .Distinct()
                                                    .Count();

        var numberOfUserDesktops = new ManagementObjectSearcher(scope, new SelectQuery("select * from win32_Perfrawdata_TermService_TerminalServicesSession")).Get().Count - 1; // don't count Service desktop
        var numberOflogonUIProcesses = Process.GetProcessesByName("LogonUI", machineName).Length;

        if (numberOflogonUIProcesses >= numberOfUserDesktops) {
            if (numberOfLogonSessionsWithExplorer > 0)
                return PCUserStatuses.Locked;
            else
                return PCUserStatuses.LoggedOff;
        }
        else
            return PCUserStatuses.InUse;
    }
    catch {
        return PCUserStatuses.Unknown;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...