Использование SHGetSpecialFolderPath для извлечения папки приложения, к которой также могут обращаться пользователи, не являющиеся администраторами, какой CSIDL выбрать? - PullRequest
7 голосов
/ 23 февраля 2011

В моем приложении я храню на каждой машине несколько файлов в папке приложения.

Упрощенная версия реального случая такова:

..\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 ]

5 голосов
/ 23 февраля 2011

Я думаю, вы хотите использовать CSIDL_COMMON_APPDATA для файлов, которые не зависят от пользователя. Если вы предположили (в своем коде), что файлы, хранящиеся в CSIDL_APPDATA, являются общими для пользователей, это недопустимо.

0 голосов
/ 30 марта 2011

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

Проблема, с которой я столкнулся, до сих пор не ясна, но я подозреваю, что это связано с тем, что login.ini является зарезервированным словом (только недавно, возможно, после недавнего обновления Windows).

Я уже задавал этот вопрос .

...