Как я могу получить путь к специальной папке Windows для конкретного пользователя?

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

Есть ли способ сделать это, основываясь только на имени пользователя? Если нет, каков минимальный объем информации, необходимой для учетной записи пользователя? Я бы предпочел не требовать пароль пользователя.

(Вот вопрос ).)

Ответ 1

Я бы установил куст реестра пользователей и посмотрел на значение пути. Да, это неоптимальное решение по всем указанным причинам (плохой передовой совместимость и т.д.). Однако, как и многие другие вещи в Windows, MS не предоставила API-подход к тому, что вы хотите сделать, поэтому он имеет лучший доступный вариант.

Вы можете получить SID (не GUID) пользователя, используя LookupAccountName. Вы можете загрузить куст реестра пользователей с помощью LoadUserProfile, но, к сожалению, для этого также требуется токен пользователя, который потребует их пароля. К счастью, вы можете вручную загрузить улей с помощью RegLoadKey в произвольное место, прочитать данные и выгрузить его (я думаю).

Да, это боль, и да, возможно, он сломается в будущих версиях Windows. Возможно, к тому времени MS предоставит API для этого, переложит его в более старые версии Windows и автоматически распространит его через обновление Windows... но я бы не задерживал дыхание.

P.S. Эта информация предназначена для увеличения информации, предоставленной в вашем родном вопросе, включая отказ от ответственности.

Ответ 2

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

http://msdn.microsoft.com/en-us/library/bb762181(VS.85).aspx

Изменить: похоже, LogonUser предоставит токен другому пользователю, который вам нужен.

Ответ 3

Вы можете попытаться вызвать ImpersonateLoggedOnUser(), чтобы изменить токен пользователя для другого пользователя, а затем передать его SHGetFolderPath(). Основываясь на документе для ImpersonateLoggedOnUser(), похоже, вы можете вызвать LogonUser(), чтобы получить токен для определенного пользователя.

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

Ответ 4

Эта информация хранится в реестре в ключе "HKEY_USERS\S-1-5-21-616815238-485949776-2992451252-3228\Software\Microsoft\Windows\CurrentVersion\Explorer\Папки пользовательской оболочки".

"S-1-5-21-616815238-485949776-2992451252-3218" является идентификатором пользователя. Вам нужно получить этот идентификатор GUID, чтобы найти соответствующий ключ и прочитать его.

В этот пример использует функцию SHGetFolderPath, которую вы упоминаете, и есть список со всеми специальными папками, которые могут быть полезны.

ПРИМЕЧАНИЕ. Microsoft не рекомендует использовать раздел реестра, поскольку он все еще существует только для обратной совместимости