Как сохранить настройки приложения в приложении Windows Forms?

Я хочу добиться очень простого: у меня есть приложение Windows Forms (.NET 3.5), которое использует путь для чтения информации. Этот путь может быть изменен пользователем с помощью предоставленной мной формы опций.

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

Насколько я понимаю, доступны три варианта:

  • Файл ConfigurationSettings (appname.exe.config)
  • Реестр
  • Пользовательский файл XML

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

Означает ли это, что я должен использовать собственный XML-файл для сохранения настроек конфигурации?

Если да, то я хотел бы увидеть пример этого кода (C#).

Я видел и другие дискуссии на эту тему, но мне это все еще непонятно.

Это приложение .NET WinForms? Если да, то на какой версии .NET вы работаете?

Portman 17.01.2009 16:20

Да, это приложение WinForms .NET framework версии 3.5.

Fueled 17.01.2009 18:15

нужно экономить пароли или секреты значений? Может требуется какой-нибудь шифрование

Kiquenet 21.09.2015 09:31
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
603
3
482 565
14
Перейти к ответу Данный вопрос помечен как решенный

Ответы 14

Реестр запрещен. Вы не уверены, имеет ли пользователь, использующий ваше приложение, достаточные права для записи в реестр.

Вы можете использовать файл app.config для сохранения настроек уровня приложения (которые одинаковы для всех пользователей, использующих ваше приложение).

Я бы сохранил пользовательские настройки в XML-файле, который будет сохранен в Изолированное хранилище или в каталоге SpecialFolder.ApplicationData.

Кроме того, начиная с .NET 2.0, можно сохранять значения обратно в файл app.config.

Однако используйте реестр, если вам нужны настройки для каждого входа / пользователя.

thenonhacker 17.01.2009 18:31

@thenonhacker: Или используйте Environment.GetFolderPath (Environment.SpecialFolder.Applicat‌ ionData)

Kenny Mann 10.09.2009 18:02

@Kb. Да, и анонимная структура внутри союза тоже. Не хорошая причина не использовать его, если вы ориентируетесь на платформу Windows (не меньше C#).

bobobobo 24.02.2012 20:48

Не мог бы кто-нибудь объяснить, как «можно сохранить значения обратно в файл app.config (которые одинаковы для каждого пользователя, использующего ваше приложение)»? Я с @Hans Passant в его ответе: «Класс ApplicationSettings не поддерживает сохранение настроек в файл app.config». Я нашел единственный способ сохранить настройки в app.config в папке exe - это использовать настройки пользовательской области вместе с настраиваемым SettingsProvider, подобным этому: PortableSettingsProvider.

minnow 14.09.2012 03:27

@thenonhacker - Реестр не требуется и не должен использоваться для хранения настроек приложения - никогда. System.Environment.SpecialFolder.LocalApplicationData - это локальная папка для каждого пользователя. .ApplicationData - это перемещаемая папка для каждого пользователя. См. msdn.microsoft.com/en-us/library/…

deegee 29.06.2013 01:52

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

Kesty 17.02.2017 12:10

Основным недостатком реестра является сложность экспорта / копирования настроек на другой компьютер. Но я не согласен с тем, что «Вы не уверены, имеет ли пользователь, который использует ваше приложение, достаточные права для записи в реестр» - в HKEY_CURRENT_USER у вас всегда есть права на запись. Это можно запретить, но файловая система также может быть недоступна для текущего пользователя (все возможные папки TEMP и т. д.).

i486 20.10.2017 11:32

Много мнений (хорошо), но так или иначе очень мало убедительной информации (config -v- Registry). @DeeGee не придирается к вам, но вы кажетесь настолько непреклонным, что никогда не следует использовать реестр. Иронично, что рассматриваемая программная платформа использует более 400 параметров личного реестра, и черт его знает, сколько параметров глобального реестра. Предположил бы, что MS не думает, что реестр нельзя использовать «когда-либо». Вы опытный программист, а я опытный специалист по инфраструктуре и среде, поэтому я знаю, что в некоторых ситуациях есть веские причины не позволять AppData перемещаться среди пользователей.

EyePeaSea 15.12.2018 22:16

@EyePeaSea - Я согласен с вами, что в схеме вещей на самом деле не имеет значения, какой метод выберет разработчик, у любого метода есть свои плюсы и минусы. Однако я по-прежнему считаю, что программные приложения должны использовать предоставленные пользовательские папки для хранения данных приложения, включая файлы настроек. Раздутый реестр и огромное количество потерянных ключей - это реальная проблема. Единственный раз, когда я буду использовать реестр, - это когда у меня есть некоторые элементы, которые я не хочу размещать в файле .ini, например лицензионные ключи для регистрации программного обеспечения или сохраняющиеся элементы кросс-версии.

deegee 16.12.2018 05:19

Насколько я могу судить, .NET поддерживает сохранение настроек с помощью встроенного средства настройки приложения:

The Application Settings feature of Windows Forms makes it easy to create, store, and maintain custom application and user preferences on the client computer. With Windows Forms application settings, you can store not only application data such as database connection strings, but also user-specific data, such as user application preferences. Using Visual Studio or custom managed code, you can create new settings, read them from and write them to disk, bind them to properties on your forms, and validate settings data prior to loading and saving. - http://msdn.microsoft.com/en-us/library/k4s6c3a0.aspx

Неправда .. см. Ответ Аку выше. это возможно с помощью Settings и ApplicationSettingsBase

Gishu 17.01.2009 16:16
Ответ принят как подходящий

Если вы работаете с Visual Studio, довольно легко получить постоянные настройки. Щелкните правой кнопкой мыши проект в обозревателе решений и выберите «Свойства». Выберите вкладку «Настройки» и щелкните гиперссылку, если настройки не существуют.

Используйте вкладку «Настройки» для создания настроек приложения. Visual Studio создает файлы Settings.settings и Settings.Designer.settings, которые содержат одноэлементный класс Settings, унаследованный от ApplicationSettingsBase. Вы можете получить доступ к этому классу из своего кода для чтения / записи настроек приложения:

Properties.Settings.Default["SomeProperty"] = "Some Value";
Properties.Settings.Default.Save(); // Saves settings in application configuration file

Этот метод применим как для консоли, так и для Windows Forms и других типов проектов.

Обратите внимание, что вам нужно установить свойство сфера ваших настроек. Если вы выберете Область применения, тогда Settings.Default. <Your property> будет только для чтения.

Ссылка: Как: записывать пользовательские настройки во время выполнения с помощью C# - Microsoft Docs

Если у меня есть решение, будет ли это применяться ко всему решению или к каждому проекту?

franko_camron 27.10.2011 22:03

По умолчанию метод Settings.Default.Save() ничего не делает. Вы должны использовать другого провайдера. См .: geek-republic.com/2010/11/08/c-portable-settings-provider

Four 10.01.2012 00:11

@Four: у меня есть проект .NET 4.0 WinApp, и мой SomeProperty не доступен только для чтения. Settings.Default.SomeProperty = 'value'; Settings.Default.Save(); работает как шарм. Или это потому, что у меня есть пользовательские настройки?

doekman 16.01.2012 14:34

@Four: когда я изменил настройку с User на Application-scope и сохранил файл, я увидел в сгенерированном коде сеттер исчез. Это также происходит с профилем клиента 4.0 ...

doekman 17.01.2012 14:28

@Four: отличная ссылка, хотя ваше утверждение, что Settings.Default.Save() ничего не делает, неверно. Как утверждает @aku в ответе, настройки области приложения доступны только для чтения: сохранение для них неэффективно. Используйте этот настраиваемый PortableSettingsProvider, чтобы сохранить настройки пользовательской области в app.config, расположенном там, где находится исполняемый файл, а не в папке AppData пользователя. Нет, в целом не очень хорошо, но я использую его во время разработки, чтобы использовать одни и те же настройки от компиляции к компиляции (без этого они переходят в новые уникальные пользовательские папки с каждой компиляцией).

minnow 14.09.2012 02:55

что делать, если у меня нет файла конфигурации? или любой файл .. у меня только один exe файл

Sreekumar P 11.03.2013 17:49

На данный момент с .NET 3.5 кажется, что вы можете просто использовать Settings.Default.SomeProperty, чтобы присвоить значение и получить сильное приведение типов. Кроме того, чтобы сэкономить время других (мне потребовалось некоторое время, чтобы понять это), вам нужно либо ввести Properties.Settings.Default, либо добавить using YourProjectNameSpace.Settings в начало файла. Только "Настройки" не определены / не найдены.

eselk 18.06.2013 01:07

Ошибка 2 Имя «Настройки» не существует в текущем контексте. Ответ не работает, как указано. Должен быть Properties.Settings.Default

Ian Thompson 06.11.2013 05:21

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

Mitulát báti 17.04.2014 15:37

Ох, я не вызывал метод Save. В настоящее время работает. Он хранит данные в файле конфигурации приложения.

Mitulát báti 17.04.2014 16:01

@Four в .NET4.0, я нахожу Properties.Settings.Default.SomeProperty = "sth"; работает нормально. SomeProperty находится в пользовательской области, почему?

SubmarineX 21.05.2014 16:40

Лучший / более простой ответ (и нет, не попытки повторного рассылки спама - помещаем его здесь только потому, что это самая популярная версия этого вопроса): stackoverflow.com/a/8313682/409856

downwitch 20.07.2014 08:58

Могу я заинтересовать вас 15-секундным взглядом на библиотеку (github.com/anakic/Jot), которую я создал для такого рода вещей?

anakic 07.06.2016 23:58

Сохраняются ли эти настройки, если / когда новая версия приложения устанавливается поверх предыдущей?

Cole 30.06.2016 18:26

Параметры нельзя использовать совместно между двумя приложениями (например, приложением установки и самим приложением, поэтому, если это необходимо, это решение не будет работать.

Kesty 17.02.2017 12:11

Класс ApplicationSettings не поддерживает сохранение настроек в файл app.config. Это очень задумано; приложения, которые запускаются с должным образом защищенной учетной записью (например, Vista UAC), не имеют права записи в папку установки программы.

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

Не могли бы вы расширить свое последнее предложение? Попросите повышения прав, чтобы написать app.config или написать отдельное приложение, которое будет проходить через домашние поисковые системы всех пользователей, искать user.config и редактировать их?

CannibalSmith 06.11.2009 16:00

Отдельная программа требует манифеста для запроса повышения. Погуглите asinvoker requireadministrator, чтобы найти правильный синтаксис. Редактировать user.config нецелесообразно и не нужно.

Hans Passant 06.11.2009 18:19

Предлагаемое решение с использованием web.config или app.config мне не нравится. Попробуйте прочитать свой собственный XML. Взгляните на Файлы настроек XML - больше никаких web.config.

Если вы планируете сохранить файл в том же каталоге, что и ваш исполняемый файл, вот хорошее решение, использующее формат JSON:

using System;
using System.IO;
using System.Web.Script.Serialization;

namespace MiscConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            MySettings settings = MySettings.Load();
            Console.WriteLine("Current value of 'myInteger': " + settings.myInteger);
            Console.WriteLine("Incrementing 'myInteger'...");
            settings.myInteger++;
            Console.WriteLine("Saving settings...");
            settings.Save();
            Console.WriteLine("Done.");
            Console.ReadKey();
        }

        class MySettings : AppSettings<MySettings>
        {
            public string myString = "Hello World";
            public int myInteger = 1;
        }
    }

    public class AppSettings<T> where T : new()
    {
        private const string DEFAULT_FILENAME = "settings.json";

        public void Save(string fileName = DEFAULT_FILENAME)
        {
            File.WriteAllText(fileName, (new JavaScriptSerializer()).Serialize(this));
        }

        public static void Save(T pSettings, string fileName = DEFAULT_FILENAME)
        {
            File.WriteAllText(fileName, (new JavaScriptSerializer()).Serialize(pSettings));
        }

        public static T Load(string fileName = DEFAULT_FILENAME)
        {
            T t = new T();
            if (File.Exists(fileName))
                t = (new JavaScriptSerializer()).Deserialize<T>(File.ReadAllText(fileName));
            return t;
        }
    }
}

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

Trevor 27.11.2014 00:43

О, возможно, лучшим вариантом было бы сохранить файл настроек в папке appdata пользователя.

Trevor 27.11.2014 11:27

Менять DEFAULT_FILENAME не нужно, просто позвоните в settings.Save(theFileToSaveTo); DEFAULT_FILENAME должен быть заглавными буквами как постоянный. Если вам нужно свойство чтения-записи, создайте его и задайте конструктору значение DEFAULT_FILENAME. Затем укажите значение аргумента по умолчанию null, проверьте это и используйте свое свойство в качестве значения по умолчанию. Это немного больше набора текста, но дает вам более стандартный интерфейс.

Jesse Chisholm 21.04.2015 18:31

Вам нужно будет сослаться на System.Web.Extensions.dll, если вы еще этого не сделали.

TEK 30.03.2016 22:44

Я создал целую библиотеку на основе этого ответа со многими улучшениями и сделал ее доступной в nuget: github.com/Nucs/JsonSettings

NucS 18.12.2017 00:35

Есть еще один способ сохранить / загрузить настройки, использующие формат json, - это библиотека Config4Net, она также может отображать окно для редактирования этих настроек во время выполнения. Особенно, если вы хотите создать форму настроек, которая привязывается к определенному объекту настроек, поэтому с этой библиотекой остается всего одна строка, и все готово.

No Em 04.02.2018 15:07

Не записывайте в ту же папку, что и ваш exe, если вы не работаете над приложением, которое, как вы знаете, будет установлено только в appdata. Если ваш exe установлен в любую из программных папок, то вряд ли пользователь сможет сохранять там файлы. Почему нет? Оказалось, что разрешение приложению сохранять файлы туда, где хранятся dll и exe, было лазейкой в ​​безопасности.

Andy 18.12.2020 19:11

Аргумент registry / configurationSettings / XML все еще кажется очень активным. Я использовал их все по мере развития технологий, но мой любимый основан на Система трида в сочетании с Изолированное хранилище.

Следующий пример позволяет хранить объекты с именем properties в файле в изолированном хранилище. Такой как:

AppSettings.Save(myobject, "Prop1,Prop2", "myFile.jsn");

Свойства могут быть восстановлены с помощью:

AppSettings.Load(myobject, "myFile.jsn");

Это всего лишь образец, не предлагающий лучших практик.

internal static class AppSettings
{
    internal static void Save(object src, string targ, string fileName)
    {
        Dictionary<string, object> items = new Dictionary<string, object>();
        Type type = src.GetType();

        string[] paramList = targ.Split(new char[] { ',' });
        foreach (string paramName in paramList)
            items.Add(paramName, type.GetProperty(paramName.Trim()).GetValue(src, null));

        try
        {
            // GetUserStoreForApplication doesn't work - can't identify.
            // application unless published by ClickOnce or Silverlight
            IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForAssembly();
            using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(fileName, FileMode.Create, storage))
            using (StreamWriter writer = new StreamWriter(stream))
            {
                writer.Write((new JavaScriptSerializer()).Serialize(items));
            }

        }
        catch (Exception) { }   // If fails - just don't use preferences
    }

    internal static void Load(object tar, string fileName)
    {
        Dictionary<string, object> items = new Dictionary<string, object>();
        Type type = tar.GetType();

        try
        {
            // GetUserStoreForApplication doesn't work - can't identify
            // application unless published by ClickOnce or Silverlight
            IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForAssembly();
            using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(fileName, FileMode.Open, storage))
            using (StreamReader reader = new StreamReader(stream))
            {
                items = (new JavaScriptSerializer()).Deserialize<Dictionary<string, object>>(reader.ReadToEnd());
            }
        }
        catch (Exception) { return; }   // If fails - just don't use preferences.

        foreach (KeyValuePair<string, object> obj in items)
        {
            try
            {
                tar.GetType().GetProperty(obj.Key).SetValue(tar, obj.Value, null);
            }
            catch (Exception) { }
        }
    }
}

Или еще лучше; использовать DataContractJsonSerializer

Boczek 24.11.2011 20:13

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

Могу представить два хороших варианта:

  • Версия со строгой типизацией и
  • Объектно-ориентированная версия.

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

Преимущество объектно-ориентированной версии состоит в том, что новые настройки могут быть добавлены во время выполнения. Но у вас нет строго типизированных имен и значений. Будьте осторожны со строковыми идентификаторами. При получении значения необходимо знать тип данных, сохраненный ранее.

Вы можете найти код обеих полнофункциональных реализаций ЗДЕСЬ.

Другие варианты, вместо использования настраиваемого файла XML, мы можем использовать более удобный для пользователя формат файла: файл JSON или YAML.

  • Если вы используете .NET 4.0 dynamic, эта библиотека действительно проста в использовании. (сериализация, десериализация, поддержка вложенных объектов и упорядочение вывода по желанию + объединение нескольких настроек в одну) JsonConfig (использование эквивалентно ApplicationSettingsBase)
  • Для библиотеки конфигурации .NET YAML ... Я не нашел такой, как легко использовать как JsonConfig

Вы можете хранить свой файл настроек в нескольких специальных папках (для всех пользователей и для каждого пользователя), как указано здесь Environment.SpecialFolder - перечисление, и в нескольких файлах (по умолчанию только для чтения, для каждой роли, для каждого пользователя и т. д.)

Если вы решите использовать несколько настроек, вы можете объединить эти настройки: например, объединение настроек по умолчанию + BasicUser + AdminUser. Вы можете использовать свои собственные правила: последнее переопределяет значение и т. д.

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

Вот пример для хранения позиции и размера формы.

Объект данных конфигурации строго типизирован и прост в использовании:

[Serializable()]
public class CConfigDO
{
    private System.Drawing.Point m_oStartPos;
    private System.Drawing.Size m_oStartSize;

    public System.Drawing.Point StartPos
    {
        get { return m_oStartPos; }
        set { m_oStartPos = value; }
    }

    public System.Drawing.Size StartSize
    {
        get { return m_oStartSize; }
        set { m_oStartSize = value; }
    }
}

Класс менеджера для сохранения и загрузки:

public class CConfigMng
{
    private string m_sConfigFileName = System.IO.Path.GetFileNameWithoutExtension(System.Windows.Forms.Application.ExecutablePath) + ".xml";
    private CConfigDO m_oConfig = new CConfigDO();

    public CConfigDO Config
    {
        get { return m_oConfig; }
        set { m_oConfig = value; }
    }

    // Load configuration file
    public void LoadConfig()
    {
        if (System.IO.File.Exists(m_sConfigFileName))
        {
            System.IO.StreamReader srReader = System.IO.File.OpenText(m_sConfigFileName);
            Type tType = m_oConfig.GetType();
            System.Xml.Serialization.XmlSerializer xsSerializer = new System.Xml.Serialization.XmlSerializer(tType);
            object oData = xsSerializer.Deserialize(srReader);
            m_oConfig = (CConfigDO)oData;
            srReader.Close();
        }
    }

    // Save configuration file
    public void SaveConfig()
    {
        System.IO.StreamWriter swWriter = System.IO.File.CreateText(m_sConfigFileName);
        Type tType = m_oConfig.GetType();
        if (tType.IsSerializable)
        {
            System.Xml.Serialization.XmlSerializer xsSerializer = new System.Xml.Serialization.XmlSerializer(tType);
            xsSerializer.Serialize(swWriter, m_oConfig);
            swWriter.Close();
        }
    }
}

Теперь вы можете создать экземпляр и использовать в своей форме события загрузки и закрытия:

    private CConfigMng oConfigMng = new CConfigMng();

    private void Form1_Load(object sender, EventArgs e)
    {
        // Load configuration
        oConfigMng.LoadConfig();
        if (oConfigMng.Config.StartPos.X != 0 || oConfigMng.Config.StartPos.Y != 0)
        {
            Location = oConfigMng.Config.StartPos;
            Size = oConfigMng.Config.StartSize;
        }
    }

    private void Form1_FormClosed(object sender, FormClosedEventArgs e)
    {
        // Save configuration
        oConfigMng.Config.StartPos = Location;
        oConfigMng.Config.StartSize = Size;
        oConfigMng.SaveConfig();
    }

И созданный XML-файл также доступен для чтения:

<?xml version = "1.0" encoding = "utf-8"?>
<CConfigDO xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd = "http://www.w3.org/2001/XMLSchema">
  <StartPos>
    <X>70</X>
    <Y>278</Y>
  </StartPos>
  <StartSize>
    <Width>253</Width>
    <Height>229</Height>
  </StartSize>
</CConfigDO>

У меня это отлично работает в разработке, но когда я развертываю приложение, средний пользователь не имеет доступа к папке c:\program files\my application, поэтому сохранение настроек вызывает ошибку. Вместо этого я пытаюсь сохранить xml-файл в AppData, но мне просто интересно, есть ли очевидный способ решения этой проблемы, поскольку этот подход, похоже, сработал для вас.

Philip Stratford 01.03.2017 21:02

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

Dieter Meemken 06.03.2017 00:16

@PhilipStratford Может быть, папка AppData - это вариант для вас, см. C# получает путь к% AppData%, как упоминалось летающий змей.

Dieter Meemken 06.03.2017 15:01

Спасибо, я это уже реализовал, сохранив xml-файл в папке AppDate. Мне просто интересно, есть ли простой способ сохранить его в папке приложения в соответствии с вашим примером, поскольку я предполагал, что вы заставили его работать. Не волнуйтесь, папка AppData, вероятно, в любом случае лучше!

Philip Stratford 07.03.2017 19:39

Я хотел поделиться библиотекой, которую я создал для этого. Это крошечная библиотека, но большое улучшение (ИМХО) по сравнению с файлами .settings.

Библиотека называется Джот (GitHub). Вот старый Статья Code Project я про него писал.

Вот как вы могли бы использовать его для отслеживания размера и местоположения окна:

public MainWindow()
{
    InitializeComponent();

    _stateTracker.Configure(this)
        .IdentifyAs("MyMainWindow")
        .AddProperties(nameof(Height), nameof(Width), nameof(Left), nameof(Top), nameof(WindowState))
        .RegisterPersistTrigger(nameof(Closed))
        .Apply();
}

Преимущество по сравнению с файлами .settings: Здесь значительно меньше кода, и он намного менее подвержен ошибкам, поскольку вам нужно только упомянуть каждое свойство однажды.

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

Хранение, сериализация и т. д. Полностью настраиваются. Когда целевые объекты создаются контейнером IoC, вы можете [подключить его] [], чтобы он автоматически применял отслеживание ко всем объектам, которые он разрешает, так что все, что вам нужно сделать, чтобы сделать свойство постоянным, - это установить [Trackable] атрибут на нем.

Он легко настраивается, и вы можете настроить: - когда данные сохраняются и применяются глобально или для каждого отслеживаемого объекта - как это сериализуется - где он хранится (например, файл, база данных, онлайн, изолированное хранилище, реестр) - правила, которые могут отменить применение / сохранение данных для свойства

Поверьте, библиотека на высшем уровне!

public static class SettingsExtensions
{
    public static bool TryGetValue<T>(this Settings settings, string key, out T value)
    {
        if (settings.Properties[key] != null)
        {
            value = (T) settings[key];
            return true;
        }

        value = default(T);
        return false;
    }

    public static bool ContainsKey(this Settings settings, string key)
    {
        return settings.Properties[key] != null;
    }

    public static void SetValue<T>(this Settings settings, string key, T value)
    {
        if (settings.Properties[key] == null)
        {
            var p = new SettingsProperty(key)
            {
                PropertyType = typeof(T),
                Provider = settings.Providers["LocalFileSettingsProvider"],
                SerializeAs = SettingsSerializeAs.Xml
            };
            p.Attributes.Add(typeof(UserScopedSettingAttribute), new UserScopedSettingAttribute());
            var v = new SettingsPropertyValue(p);
            settings.Properties.Add(p);
            settings.Reload();
        }
        settings[key] = value;
        settings.Save();
    }
}

«Означает ли это, что я должен использовать собственный XML-файл для сохранения настроек конфигурации?» Нет, не обязательно. Для таких операций мы используем SharpConfig.

Например, если такой файл конфигурации

[General]
# a comment
SomeString = Hello World!
SomeInteger = 10 # an inline comment

Мы можем получить такие значения

var config = Configuration.LoadFromFile("sample.cfg");
var section = config["General"];

string someString = section["SomeString"].StringValue;
int someInteger = section["SomeInteger"].IntValue;

Он совместим с .NET 2.0 и выше. Мы можем создавать файлы конфигурации на лету и сохранять их позже.

Источник: http://sharpconfig.net/
GitHub: https://github.com/cemdervis/SharpConfig

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

Во-первых, вам нужно различать, хотите ли вы использовать настройки приложения или AppSettings в вашем файле *.exe.config (он же App.config в Visual Studio) - есть принципиальные отличия,здесь описано.

Оба предоставляют разные способы сохранения изменений:

  • AppSettings позволяет вам читать и записывать непосредственно в файл конфигурации (через config.Save(ConfigurationSaveMode.Modified);, где конфигурация определена как config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);).
  • настройки приложения разрешает чтение, но если вы записываете изменения (через Properties.Settings.Default.Save();), они будут записаны для каждого пользователя, сохранены в специальном месте (например, C:\Documents and Settings\USERID\Local Settings\Application Data\FIRMNAME\WindowsFormsTestApplicati_Url_tdq2oylz33rzq00sxhvxucu5edw2oghw\1.0.0.0). Как указано в ответе Ганс Пассан упомянул, это связано с тем, что пользователь обычно имеет ограниченные права на программные файлы и не может писать в них, не вызывая приглашение UAC. Недостатком является то, что если вы добавляете ключи конфигурации в будущем, вам необходимо синхронизировать их с каждым профилем пользователя.

Примечание: Как упоминалось в вопросе, существует 3-й вариант:. Если вы обрабатываете файл конфигурации как XML-документ,, вы можете загружать, изменять и сохранять его с помощью класса System.Xml.Linq.XDocument. Нет необходимости использовать собственный XML-файл, вы можете прочитать существующий файл конфигурации; для запроса элементов вы даже можете использовать запросы Linq. Я привел пример здесь, посмотрите там в ответе функцию GetApplicationSetting.

Если вам требуется шифрование для защиты ваших ценностей,, посмотрите ответ это.

@NoChance - Пожалуйста, рад, что я смог вам помочь!

Matt 27.01.2020 14:17

Хороший! Наконец-то во всем разобрался ???

Momoro 24.03.2020 08:49

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