Использование SHGetSpecialFolderPath для извлечения папки приложения, к которой также могут обращаться пользователи, не являющиеся администраторами, какой CSIDL выбрать?
В моем приложении я храню на каждой машине некоторые файлы в папке приложения.
Упрощенная версия реального случая такова:
..\Project1\LoginHistory (login history file - common for all users)
..\Project1\Translations (localization files - common for all users)
..\Project1\FormSettings\User1\ (this contains an ini file per form for User1)
..\Project1\FormSettings\UserN\ (this contains an ini file per form for UserN)
Таким образом, вы можете понять, почему я использую это: чтобы сохранить некоторые данные, относящиеся к компьютеру (вспомните последние логины, сделанные с этого компьютера, своего рода MRU), для хранения строк перевода или сторонних компонентов (они извлекаются во время выполнения из exe ресурсы) и для сохранения некоторых пользовательских данных (например, размер формы). Реальный случай более сложный, но, по крайней мере, вы можете понять, что есть "общая папка" и "пользовательские папки".
Теперь я хотел бы сохранить эту структуру, чтобы все мои файлы находились в одной папке..\Project1 (+ подпапки). Даже потому, что пользователи не являются пользователями Windows, но они являются пользователями SQL Server.
У меня вопрос, какую папку выбрать ..\
,
В настоящее время я (успешно) использую этот код для получения ..\
uses ShlObj;
function GetSpecialFolder(const CSIDL: integer) : string;
var
RecPath : PWideChar;
begin
RecPath := StrAlloc(MAX_PATH);
try
FillChar(RecPath^, MAX_PATH, 0);
if SHGetSpecialFolderPath(0, RecPath, CSIDL, false)
then result := RecPath
else result := '';
finally
StrDispose(RecPath);
end;
end;
И я называю это с
GetSpecialFolder(CSIDL_APPDATA)
Где список CDISL определяется здесь.
GetSpecialFolder(CSIDL_APPDATA)
возвращается C:\Users\username\AppData\Roaming
в Windows 7.
Так что раньше это работало, но недавно я получил жалобу от какого-то клиента, которая, по-видимому, напрямую связана с проблемами чтения / записи в этих папках. (например C:\Users\username\AppData\Roaming\Project1\LoginHistory
- используя папки, перечисленные выше).
Итак, мой вопрос: это правильно использовать CSIDL_APPDATA
? У вас есть другое предложение? Есть ли вероятность, что в некоторых ОС или у некоторых пользователей с действительно ограниченными привилегиями могут возникнуть проблемы с чтением / записью в этой папке?
Пожалуйста, помните, что я не хотел бы иметь более одной корневой папки для моих файлов.
2 ответа
Подход, который я использую в конце концов, верен. Поскольку мне действительно не нужны общие файлы для моего приложения (имеет смысл, что все временные файлы зависят от пользователя - потому что несколько общих вещей хранятся в БД) CSIDL_APPDATA
это хорошее место.
Проблема, с которой я столкнулся, до сих пор не ясна, но я подозреваю, что это связано с тем, что login.ini является зарезервированным словом (возможно, только недавно, после некоторого недавнего обновления Windows).
Я уже задавал этот вопрос.
Я думаю, что вы хотите использовать CSIDL_COMMON_APPDATA
для файлов, которые не являются специфичными для пользователя. Если вы предполагали (в своем коде), что файлы хранятся в CSIDL_APPDATA
являются общими для пользователей, что не допускается.