Поддержка быстрого переключения между пользователями

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

Процессы в коммутируемом сеансе входа в систему продолжают работать как прежде. Они могут продолжать обрабатывать данные, связываясь с системой, и таща к экранному буферу как прежде. Однако, потому что они выключаются, они не получают ввод от клавиатуры и мыши. Точно так же, если бы они должны были проверить, монитор, казалось бы, был бы в режиме ожидания. В результате это может принести преимущества некоторым приложениям для корректировки их поведения в то время как в коммутируемом состоянии, чтобы избежать тратить впустую системные ресурсы.

В то время как быстрое переключение между пользователями является удобной функцией пользователей, оно действительно обеспечивает несколько проблем для разработчиков приложений. Приложения, полагающиеся на эксклюзивный доступ к определенным ресурсам, возможно, должны изменить свое поведение жить в среде быстрого переключения между пользователями. Например, приложение, хранящее временные данные в /tmp когда второй экземпляр, работающий при различном пользователе, пытается изменить те же файлы в том каталоге, может столкнуться с проблемами.

Инструкции для поддержки быстрого переключения между пользователями

Для поддержки быстрого переключения между пользователями существуют определенные инструкции, за которыми необходимо следовать в разработке приложений. Большинство этих инструкций описывает безопасные способы идентифицировать и совместно использовать системные ресурсы. Сводка этих инструкций следующие:

При тегировании специализированных ресурсов с сеансом ID необходим для различения их от подобных ресурсов, создаваемых приложениями в различном сеансе. Уровень безопасности системы присваивает уникальный идентификатор каждому сеансу входа в систему. Слияние этого ID в файл кэша или временные имена каталогов может предотвратить конфликты пространства имен при создании этих файлов. Посмотрите Получающую информацию Сеанса Входа в систему для получения информации о том, как получить сеанс ID.

Получение совместно использованных системных ресурсов, таких как порты TCP/IP, представляет другие проблемы в среде быстрого переключения между пользователями. Например, если Вы болтаете соединение, Вы содержите на порт или бросаете его, когда новый пользователь переключается в? То, как Вы обрабатываете эти ситуации, зависит от включенного ресурса и проект Вашего приложения. Независимо от того, как Вы обрабатываете его, необходимо знать, когда пользовательский переключатель происходит, и для которого необходимо считать раздел User Switch Notifications, описывающий уведомления, доступные приложениям.

Получение информации сеанса входа в систему

Если Ваше приложение создает файл, область общей памяти или другой объект, живущий в глобальном пространстве имен, необходимо выпустить под брендом тот объект с уникальным сеансом ID.

OS X обеспечивает доступ к информации о сеансе от двух различных платформ. Концепция безопасности включает функцию для получения сеанса ID вместе с основной информацией о сеансе входа в систему. Базовая Графическая платформа предоставляет дополнительную информацию о сеансе входа в систему, включая имя пользователя и завершился ли процесс входа в систему.

Инструкции для Использования сеанса IDs

Поскольку сеанс, IDs уникален для сеанса, используйте их для идентификации ресурсов, которые специфичны для сеанса, но которые могут все еще быть совместно использованы объектами в том же сеансе входа в систему. Например, если Ваше приложение создает область общей памяти, Вы могли бы включать сеанс ID от имени той области. Другие приложения (включая копии того же приложения) были бы в состоянии получить доступ к этой области памяти с помощью совместно используемого имени и информации о сеансе.

Можно использовать сеанс IDs в именах каталогов, чтобы собрать в группу временные файлы и сделать их проще найти. Однако все еще рекомендуется использовать mktemp семья функций для генерации случайных имен для файлов в том каталоге.

Используя концепцию безопасности

Концепция безопасности может быть соединена в любую программу, находится ли это в корневом сеансе или в сеансе входа в систему. Эта платформа включает функцию SessionGetInfo для того, чтобы получить основную информацию о текущем сеансе, включая сеанс ID и некоторые атрибуты сеанса.

Для получения сеанса ID текущего сеанса передайте значение callerSecuritySession как первый параметр к SessionGetInfo. Если у Вас, оказывается, есть сеанс ID различного сеанса входа в систему, можно использовать его для получения информации о другом сеансе. Параметры, возвращенные SessionGetInfo являются главным образом информационными и не может быть изменен; таким образом у них нет последствий на безопасности сеанса входа в систему.

Следующий пример показывает Вам, как вызвать SessionGetInfo получить сеанс ID для текущего корня или сеанса входа в систему.

#include <Security/Security.h>
 
OSStatus error;
SecuritySessionId mySession;
SessionAttributeBits sessionInfo;
 
error = SessionGetInfo(callerSecuritySession, &mySession, &sessionInfo);

ID сеанса самостоятельно является целочисленным значением, сохраняющимся на время сеанса входа в систему; посмотрите Сеансы Входа в систему Идентификации для получения дополнительной информации. Параметр битов атрибута является целочисленным значением битовой маски, предоставляющим дополнительную информацию о сеансе, такой как, является ли это корневым сеансом и имеет ли это доступную консоль. Посмотрите заголовочные файлы для описания доступных разрядных констант.

Используя базовую графическую платформу

Базовая Графическая платформа полагается на присутствие сервера окна и таким образом доступна только приложениям, работающим в сеансе входа в систему. Эта платформа включает CGSessionCopyCurrentDictionary функция для того, чтобы получить информацию о текущем сеансе входа в систему, включая идентификатор пользователя и имя.

Следующий пример показывает Вам, как получить информацию сеанса входа в систему с помощью CGSessionCopyCurrentDictionary функция. Эта функция возвращает словарь с несколькими ключами, которые можно считать для получения информации, в которой Вы нуждаетесь.

#include <CoreFoundation/CoreFoundation.h>
#include <ApplicationServices/ApplicationServices.h>
 
CFStringRef shortUserName;
CFNumberRef userUID;
CFBooleanRef userIsActive;
CFBooleanRef loginCompleted;
 
int MyCGGetSessionInfo
{
    CFDictionaryRef sessionInfoDict;
 
    sessionInfoDict = CGSessionCopyCurrentDictionary();
    if (sessionInfoDict == NULL)
    {
        printf(“Unable to get session dictionary.”);
        return(1);
    }
 
    shortUserName = CFDictionaryGetValue(sessionInfoDict,
                                        kCGSessionUserNameKey);
    userUID = CFDictionaryGetValue(sessionInfoDict,
                                        kCGSessionUserIDKey);
    userIsActive = CFDictionaryGetValue(sessionInfoDict,
                                        kCGSessionOnConsoleKey);
    loginCompleted = CFDictionaryGetValue(sessionInfoDict,
                                        kCGSessionLoginDoneKey);
}

Распределенные уведомления

До введения быстрого переключения между пользователями отправили распределенные уведомления, использование или Базовые интерфейсы Основы или Какао были поставлены любому процессу, зарегистрировавшемуся как наблюдатель. С введением быстрого переключения между пользователями в OS X v10.3, существующие интерфейсы изменились на предельное распределение к зарегистрированным процессам в текущем сеансе входа в систему. Это изменение не должно влиять на поведение большинства приложений. Для тех приложений, которые могли бы быть затронуты, новые интерфейсы были добавлены для распределительных уведомлений через границы сеанса входа в систему.

Регистрация уведомлений всем сеансам

Если необходимо отправить распределенное уведомление другим процессам, необходимо обычно делать так только к процессам в текущем сеансе входа в систему. Однако могут быть случаи, куда необходимо отправить уведомление всем процессам, независимо от их соответствующего сеанса входа в систему. Например, изменения в глобальных системой настройках влияют на все приложения, полагающиеся на те настройки.

В базовой основе, CFNotificationCenterPostNotificationWithOptions функция позволяет Вам отправлять уведомления всем сеансам входа в систему. Для использования этой функции для глобальных уведомлений передайте kCFNotificationPostToAllSessions постоянный к options параметр.

В какао, postNotificationName:object:userInfo:options: метод объекта NSDistributedNotificationCenter позволяет Вам отправлять уведомления всем сеансам входа в систему. Для использования этой функции для глобальных уведомлений передайте NSNotificationPostToAllSessions постоянный к options параметр.

Использование глобальных уведомлений должно быть минимизировано, когда это возможно. Если необходимо идентифицировать сеанс входа в систему, породивший уведомление, поместите его сеанс ID в словарь информации о пользователе уведомления. Для получения дополнительной информации о получении сеанса ID посмотрите Получающую информацию Сеанса Входа в систему.

Обработка распределенных уведомлений

Обработчик для глобального уведомления должен быть подготовлен обработать то уведомление, даже когда это прибывает из различного сеанса входа в систему. Если Ваш обработчик принимает уведомление, порожденное в том же сеансе входа в систему, Ваше приложение могло бы испытать проблемы в быстрой пользовательской коммутируемой среде. К счастью, существующие методы для распределительных уведомлений ограничивают объем поставки текущему сеансу входа в систему. Приложения, которые должны отправить глобальные уведомления, должны быть изменены для отправки тех уведомлений явно с интерфейсами, представленными в версии 10.3 OS X.

При установке приложения, чтобы получить определенное глобальное уведомление, иметь в виду, что Вы, возможно, не должны обрабатывать все экземпляры того уведомления. Например, демон в корневом сеансе мог бы использовать глобальное уведомление для передачи с процессом в активном сеансе. В этой ситуации использование глобального уведомления предпочтительно, потому что у демона нет знания программ в сеансах входа в систему. Путем широковещательной передачи ко всем сеансам уведомление, как гарантируют, достигнет активного сеанса. Приложения в неактивных сеансах просто проигнорировали бы уведомление.

Отключение многократной сеансовой поддержки

Если потребность возникает, можно сказать OS X не запускать приложение больше чем в одном сеансе входа в систему. Этой опции нужно избежать если возможный; однако, если Вы неспособны получить свое приложение, работающее соответственно в многократных сеансах входа в систему, Вы могли бы рассмотреть использование его.

Для отключения многократной сеансовой поддержки приложения включайте LSMultipleInstancesProhibited, вводят информационный список свойств приложения. Если этот ключ присутствует и набор к истине, Launch Services отклоняет попытки запустить второй экземпляр Вашего приложения в любом сеансе входа в систему. Этот ключ работает и на запуск Вашего приложения через многократные сеансы и для запуска второго экземпляра Вашего приложения в том же сеансе. В обоих случаях Launch Services возвращает ошибку обработке вызовов, указывающей причину отказа.

Для получения дополнительной информации о том, как использовать ключ LSMultipleInstancesProhibited, см. “Ключевую Ссылку Списка свойств” в Инструкциях по Конфигурации Во время выполнения.