Использование 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 являются общими для пользователей, что не допускается.

Другие вопросы по тегам