Что является лучшим способом, чтобы хранить пользовательские настройки для приложения a.NET ?


У меня есть приложение .NET 2.0 Windows Forms. Где лучше всего хранить пользовательские настройки (учитывая рекомендации Windows)?

некоторые указывали на Application.LocalUserAppDataPath. Однако это создает структуру папок, например:

C:Documents и settingsимя_пользователяLocal НастройкиПриложения Datacompany_nameproduct_nameproduct_version

Если я выпущу версию 1 своего приложения и сохраню там XML-файл, то выпущу версию 2, это изменится на другую папку, верно? Я бы предпочел иметь одну папку для каждого пользователя, чтобы сохранять настройки, независимо от версии приложения.

8 55

8 ответов:

Я люблю использовать встроенный Настройки Приложения. Затем вы создали поддержку для использования конструктора параметров, если вы хотите во время разработки или во время выполнения использовать:

// read setting
string setting1 = (string)Settings.Default["MySetting1"];
// save setting
Settings.Default["MySetting2"] = "My Setting Value";

// you can force a save with
Properties.Settings.Default.Save();

он сохраняет настройки в аналогичной структуре папок, как вы описываете (с версией в пути). Однако, с простым вызовом:

Properties.Settings.Default.Upgrade(); 

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

приложения .NET имеют встроенный механизм настройки, который прост в использовании. Проблема с ним, на мой взгляд, заключается в том, что он хранит эти настройки в довольно неясном каталоге, и конечные пользователи не смогут его найти. Кроме того, просто переключение с debug на release build изменяет расположение этого каталога, что означает, что любые настройки, сохраненные в одной конфигурации, теряются в другой.

по этим и другим причинам, я придумал мой собственный код для настройки Windows Forms. Это не совсем так гладко, как тот, который поставляется с .NET, но он более гибкий, и я использую его все время.

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

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

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

Я пробую некоторые методы, чтобы сохранить мои настройки просто текстовый файл, и я нашел лучший способ:

файл, хранящийся в папке приложения, для использования,настройки.txt: (внутри файла настроек одобренные комментарии, попробуйте / / комментарий)

//чтобы получить значение параметров

Settings.Get("name", "Ivan");

//для установки значения настроек

Settings.Set("name", "John");

использование:

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

//вы можете хранить также с именем раздела, чтобы использовать просто добавить имя набора разделов(section_name, name, value) и Get (section_name,name,value)

public static class Settings
{
    private static string SECTION =  typeof(Settings).Namespace;//"SETTINGS";
    private static string settingsPath = Application.StartupPath.ToString() + "\settings.txt";
    [DllImport("kernel32")]
    private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
    [DllImport("kernel32")]
    private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
    public static String GetString(String name)
    {
        StringBuilder temp = new StringBuilder(255);
        int i = GetPrivateProfileString(SECTION,name,"",temp,255,settingsPath);
        return temp.ToString();
    }
    public static String Get(String name, String defVal)
    {
        return Get(SECTION,name,defVal);
    }
    public static String Get(string _SECTION, String name, String defVal)
    {
        StringBuilder temp = new StringBuilder(255);
        int i = GetPrivateProfileString(_SECTION, name, "", temp, 255, settingsPath);
        return temp.ToString();
    }
    public static Boolean Get(String name, Boolean defVal)
    {
        return Get(SECTION, name, defVal);
    }
    public static Boolean Get(string _SECTION, String name, Boolean defVal)
    {
        StringBuilder temp = new StringBuilder(255);
        int i = GetPrivateProfileString(_SECTION,name,"",temp,255,settingsPath);
        bool retval=false;
        if (bool.TryParse(temp.ToString(),out retval))
        {
            return retval;
        } else
        {
            return retval;
        }
    }
    public static int Get(String name, int defVal)
    {
        return Get(SECTION, name, defVal);
    }
    public static int Get(string _SECTION, String name, int defVal)
    {
        StringBuilder temp = new StringBuilder(255);
        int i = GetPrivateProfileString(SECTION,name,"",temp,255,settingsPath);
        int retval=0;
        if (int.TryParse(temp.ToString(),out retval))
        {
            return retval;
        } else
        {
            return retval;
        }
    }
    public static void Set(String name, String val)
    {
        Set(SECTION, name,val);
    }
    public static void Set(string _SECTION, String name, String val)
    {
        WritePrivateProfileString(_SECTION, name, val, settingsPath);
    }
    public static void Set(String name, Boolean val)
    {
        Set(SECTION, name, val);
    }
    public static void Set(string _SECTION, String name, Boolean val)
    {
        WritePrivateProfileString(_SECTION, name, val.ToString(), settingsPath);
    }
    public static void Set(String name, int val)
    {
        Set(SECTION, name, val);
    }
    public static void Set(string _SECTION,String name, int val)
    {
        WritePrivateProfileString(SECTION, name, val.ToString(), settingsPath);
    }
}

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

Я бы предпочел использовать файловую систему вместо Реестра. Кажется, его легче поддерживать. В сценариях поддержки, если пользователю необходимо вручную открыть / изменить настройки, это было бы проще, если бы это было в файловой системе.

изолированное хранилище в основном используется для приложений, распределенных с помощью ClickOnce и запускаются в безопасной песочнице. Базовый путь определяется для вас, и вы не сможете вывести его в своем коде. Путь будет чем-то вроде "\LocalSettings\ApplicationData\IsolatedStorage\ejwnwe.302\kfiwemqi.owx\url.asdaiojwejoieajae....- не все так дружелюбно. Ваше место для хранения также ограничено.

Райан Фарли все правильно.

Я бы пошел вниз по списку папок, которые вы опубликовали, за исключением версии продукта. Вы не хотите, чтобы параметры сбрасывались после выпуска обновления.

Я фактически удаляюсь от реестра для пользовательских настроек из-за фактора отладки/следа. В настоящее время я храню только несколько основных настроек (размер окна, положение, версия файла данных) в реестре, и у меня возникло больше проблем, если обновление идет плохо или пользователь теряет второй монитор, и именно там было приложение открываю. Некоторые из них достаточно сообразительны, чтобы понять regedit, но для остальных им нужно сделать переустановку, что быстро, но я думаю, что они немного ворчат. С файловой версией все, что мне нужно сделать, это открыть XML-файл в блокноте и сделать быструю настройку.

кроме того, я хочу, чтобы мое приложение запускалось с USB-накопителя, и наличие настроек, привязанных к файлу, кажется гораздо более дружелюбным к этому процессу. Я уверен, что могу сделать какой-то код для проверки / очистки реестр, но я думаю, что большинство из нас уже устали от беспорядка реестра, который, кажется, съедает наши машины в настоящее время.

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