пятница, 30 апреля 2010 г.

Опасайтесь перемещаемых профилей пользователя

Это перевод Beware of roaming user profiles. Автор: Реймонд Чен. Входит в книгу The Old New Thing.

Одной из слабо известных возможностей Windows являются перемещаемые профили пользователей (roaming user profile). Я знаю, что они не слишком известны, потому что я часто слышу предложения о новых возможностях системы, которые не принимают в расчёт сценарий с перемещаемыми профилями пользователей. Действительно, если ваша программа поведёт себя достаточно плохо, то это может привести к потере данных (я поговорю об этом подробнее чуть позже).

Но что такое перемещаемый профиль пользователя?

Ну, ваш пользовательский профиль является набором вещей, которые находятся в вашей папке %USERPROFILE% (это не совсем точно, но достаточно хорошее приближение для цели этого поста. Важное исключение мы обсудим в другой раз). Ваша личная часть реестра хранится в %USERPROFILE%\ntuser.dat, так что ваша часть реестра также является частью вашего профиля.

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

Что это означает для вас, как программиста?

Для начала, это означает, что путь к папке пользовательского профиля может отличаться в разных сессиях. Т.е. если пользователь запускает вашу программу на компьютере A, то путь к профилю может быть C:\Documents and Settings\Fred, но если он выходит из компьютера A и запускает вашу программу на компьютере B, то папка его профиля может измениться на C:\WINNT\Profiles\Fred. В частности, это означает, что файл, который вы открывали по пути C:\Documents and Settings\Fred\My Documents\Proposal.txt теперь становится C:\WINNT\Profiles\Fred\My Documents\Proposal.txt. Если в вашей программе есть возможность показа/открытия последних N использованных файлов, то вы можете столкнуться с ситуацией, когда файл не существует по старому пути. Решением будет использовать относительные, а не абсолютные пути - пути, которые относительны к виртуальным папкам оболочки (т.е. запись имени файла, относительно к CSIDL_MYDOCUMENTS), так что когда пользователь перемещается между машинами вместе со своим профилем, то программа всё ещё сможет найти его файлы.

Далее, вы не можете просто пробежаться по ключу реестра HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList, ожидая, что вы найдёте все профили пользователей или даже прочитаете или измените их, потому что копия пользовательского профиля на локальной машине может быть не актуальной. Если профиль является кэшированным перемещаемым профилем, тогда любые изменения, которые вы сделаете в нём: (1) либо пропадут, если пользователь войдёт на другой машине(2) либо приведут к тому, что старая локальная копия будет считаться новее мастер-копии на сервере, что приведёт к потере последних изменений пользователя, когда старый кэш зальётся на сервер (какой конкретно из этих двух сценариев сработает для вас зависит от времени, когда вы делаете изменения и времени, когда пользователь выходит с другой машины).

Другим следствием перемещаемого пользовательского профиля является то, что ваша программа может увидеть частые изменения своей версии. Например, если на машине A установлена версия 1 вашей программы, а на машине B стоит версия 2, то обе версии будут работать с одним и тем же профилем пользователя. Если обе версии используют один и тот же ключ реестра или одни и тот же файл для сохранения своих настроек, то тогда вашему формату хранения настроек лучше бы быть совместимым в обе стороны или у вас будут большие проблемы. Это особенно болезненно для компонентов ОС, которым приходится поддерживать двойную совместимость с системами времён Windows NT 4 (Windows NT 3.51 имела другую модель для перемещаемых профилей пользователя).

И ещё одно следствие перемещаемых профилей пользователя применяется для служб. До Windows XP, если служба держит ключ реестра открытым после выхода пользователя, тогда улей реестра не может быть выгружен и, соответственно, (1) тратит память для профиля пользователя, хотя он уже вышел, и (2) не даёт изменениям в локальной копии пользовательской части реестра скопироваться на сервер. Эта проблема "утечки улья" была столь серьёзна, что в Windows XP нам пришлось относится более агрессивно к службам, которые долго держат открытыми ключи реестра. Вы можете прочитать об этом больше по первой ссылке в этом посте.

2 комментария:

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку.

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.

Примечание. Отправлять комментарии могут только участники этого блога.