Я хочу добиться очень простого: у меня есть приложение Windows Forms (.NET 3.5), которое использует путь для чтения информации. Этот путь может быть изменен пользователем с помощью предоставленной мной формы опций.
Теперь я хочу сохранить значение пути в файл для дальнейшего использования. Это будет одна из многих настроек, сохраненных в этом файле. Этот файл будет находиться прямо в папке приложения.
Насколько я понимаю, доступны три варианта:
Я читал, что файл конфигурации .NET не предназначен для сохранения значений обратно в него. Что касается реестра, хотелось бы от него уйти как можно дальше.
Означает ли это, что я должен использовать собственный XML-файл для сохранения настроек конфигурации?
Если да, то я хотел бы увидеть пример этого кода (C#).
Я видел и другие дискуссии на эту тему, но мне это все еще непонятно.
Да, это приложение WinForms .NET framework версии 3.5.
нужно экономить пароли или секреты значений? Может требуется какой-нибудь шифрование





Реестр запрещен. Вы не уверены, имеет ли пользователь, использующий ваше приложение, достаточные права для записи в реестр.
Вы можете использовать файл app.config для сохранения настроек уровня приложения (которые одинаковы для всех пользователей, использующих ваше приложение).
Я бы сохранил пользовательские настройки в XML-файле, который будет сохранен в Изолированное хранилище или в каталоге SpecialFolder.ApplicationData.
Кроме того, начиная с .NET 2.0, можно сохранять значения обратно в файл app.config.
Однако используйте реестр, если вам нужны настройки для каждого входа / пользователя.
@thenonhacker: Или используйте Environment.GetFolderPath (Environment.SpecialFolder.Applicat ionData)
@Kb. Да, и анонимная структура внутри союза тоже. Не хорошая причина не использовать его, если вы ориентируетесь на платформу Windows (не меньше C#).
Не мог бы кто-нибудь объяснить, как «можно сохранить значения обратно в файл app.config (которые одинаковы для каждого пользователя, использующего ваше приложение)»? Я с @Hans Passant в его ответе: «Класс ApplicationSettings не поддерживает сохранение настроек в файл app.config». Я нашел единственный способ сохранить настройки в app.config в папке exe - это использовать настройки пользовательской области вместе с настраиваемым SettingsProvider, подобным этому: PortableSettingsProvider.
@thenonhacker - Реестр не требуется и не должен использоваться для хранения настроек приложения - никогда. System.Environment.SpecialFolder.LocalApplicationData - это локальная папка для каждого пользователя. .ApplicationData - это перемещаемая папка для каждого пользователя. См. msdn.microsoft.com/en-us/library/…
В реестр пользователей можно записывать (множество программ записывают туда информацию, и разрешения пользователей никогда не являются проблемой). Преимущество использования реестра перед настройками заключается в том, что если у вас есть несколько приложений, совместно использующих одну и ту же папку (например, программа установки и программа приложения), они не будут использовать одни и те же настройки.
Основным недостатком реестра является сложность экспорта / копирования настроек на другой компьютер. Но я не согласен с тем, что «Вы не уверены, имеет ли пользователь, который использует ваше приложение, достаточные права для записи в реестр» - в HKEY_CURRENT_USER у вас всегда есть права на запись. Это можно запретить, но файловая система также может быть недоступна для текущего пользователя (все возможные папки TEMP и т. д.).
Много мнений (хорошо), но так или иначе очень мало убедительной информации (config -v- Registry). @DeeGee не придирается к вам, но вы кажетесь настолько непреклонным, что никогда не следует использовать реестр. Иронично, что рассматриваемая программная платформа использует более 400 параметров личного реестра, и черт его знает, сколько параметров глобального реестра. Предположил бы, что MS не думает, что реестр нельзя использовать «когда-либо». Вы опытный программист, а я опытный специалист по инфраструктуре и среде, поэтому я знаю, что в некоторых ситуациях есть веские причины не позволять AppData перемещаться среди пользователей.
@EyePeaSea - Я согласен с вами, что в схеме вещей на самом деле не имеет значения, какой метод выберет разработчик, у любого метода есть свои плюсы и минусы. Однако я по-прежнему считаю, что программные приложения должны использовать предоставленные пользовательские папки для хранения данных приложения, включая файлы настроек. Раздутый реестр и огромное количество потерянных ключей - это реальная проблема. Единственный раз, когда я буду использовать реестр, - это когда у меня есть некоторые элементы, которые я не хочу размещать в файле .ini, например лицензионные ключи для регистрации программного обеспечения или сохраняющиеся элементы кросс-версии.
Насколько я могу судить, .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
Если вы работаете с 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
Если у меня есть решение, будет ли это применяться ко всему решению или к каждому проекту?
По умолчанию метод Settings.Default.Save() ничего не делает. Вы должны использовать другого провайдера. См .: geek-republic.com/2010/11/08/c-portable-settings-provider
@Four: у меня есть проект .NET 4.0 WinApp, и мой SomeProperty не доступен только для чтения. Settings.Default.SomeProperty = 'value'; Settings.Default.Save(); работает как шарм. Или это потому, что у меня есть пользовательские настройки?
@Four: когда я изменил настройку с User на Application-scope и сохранил файл, я увидел в сгенерированном коде сеттер исчез. Это также происходит с профилем клиента 4.0 ...
@Four: отличная ссылка, хотя ваше утверждение, что Settings.Default.Save() ничего не делает, неверно. Как утверждает @aku в ответе, настройки области приложения доступны только для чтения: сохранение для них неэффективно. Используйте этот настраиваемый PortableSettingsProvider, чтобы сохранить настройки пользовательской области в app.config, расположенном там, где находится исполняемый файл, а не в папке AppData пользователя. Нет, в целом не очень хорошо, но я использую его во время разработки, чтобы использовать одни и те же настройки от компиляции к компиляции (без этого они переходят в новые уникальные пользовательские папки с каждой компиляцией).
что делать, если у меня нет файла конфигурации? или любой файл .. у меня только один exe файл
На данный момент с .NET 3.5 кажется, что вы можете просто использовать Settings.Default.SomeProperty, чтобы присвоить значение и получить сильное приведение типов. Кроме того, чтобы сэкономить время других (мне потребовалось некоторое время, чтобы понять это), вам нужно либо ввести Properties.Settings.Default, либо добавить using YourProjectNameSpace.Settings в начало файла. Только "Настройки" не определены / не найдены.
Ошибка 2 Имя «Настройки» не существует в текущем контексте. Ответ не работает, как указано. Должен быть Properties.Settings.Default
Когда я перезапустил свою программу, мои изменения не сохранились ... были установлены настройки по умолчанию.
Ох, я не вызывал метод Save. В настоящее время работает. Он хранит данные в файле конфигурации приложения.
@Four в .NET4.0, я нахожу Properties.Settings.Default.SomeProperty = "sth"; работает нормально. SomeProperty находится в пользовательской области, почему?
Лучший / более простой ответ (и нет, не попытки повторного рассылки спама - помещаем его здесь только потому, что это самая популярная версия этого вопроса): stackoverflow.com/a/8313682/409856
Могу я заинтересовать вас 15-секундным взглядом на библиотеку (github.com/anakic/Jot), которую я создал для такого рода вещей?
Сохраняются ли эти настройки, если / когда новая версия приложения устанавливается поверх предыдущей?
Параметры нельзя использовать совместно между двумя приложениями (например, приложением установки и самим приложением, поэтому, если это необходимо, это решение не будет работать.
Класс ApplicationSettings не поддерживает сохранение настроек в файл app.config. Это очень задумано; приложения, которые запускаются с должным образом защищенной учетной записью (например, Vista UAC), не имеют права записи в папку установки программы.
Бороться с системой можно с помощью класса ConfigurationManager. Но тривиальный обходной путь - войти в конструктор настроек и изменить область действия параметра на Пользователь. Если это вызывает трудности (скажем, настройка актуальна для каждого пользователя), вам следует поместить функцию «Параметры» в отдельную программу, чтобы вы могли запросить запрос на повышение привилегий. Или откажитесь от настройки.
Не могли бы вы расширить свое последнее предложение? Попросите повышения прав, чтобы написать app.config или написать отдельное приложение, которое будет проходить через домашние поисковые системы всех пользователей, искать user.config и редактировать их?
Отдельная программа требует манифеста для запроса повышения. Погуглите asinvoker requireadministrator, чтобы найти правильный синтаксис. Редактировать user.config нецелесообразно и не нужно.
Предлагаемое решение с использованием 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 на абсолютный путь, если вы хотите сохранить в другой каталог. Я думаю, что чаще всего файл сохраняется в том же каталоге, что и приложение, или в подкаталоге, если вы не сохраняете их в реестре.
О, возможно, лучшим вариантом было бы сохранить файл настроек в папке appdata пользователя.
Менять DEFAULT_FILENAME не нужно, просто позвоните в settings.Save(theFileToSaveTo); DEFAULT_FILENAME должен быть заглавными буквами как постоянный. Если вам нужно свойство чтения-записи, создайте его и задайте конструктору значение DEFAULT_FILENAME. Затем укажите значение аргумента по умолчанию null, проверьте это и используйте свое свойство в качестве значения по умолчанию. Это немного больше набора текста, но дает вам более стандартный интерфейс.
Вам нужно будет сослаться на System.Web.Extensions.dll, если вы еще этого не сделали.
Я создал целую библиотеку на основе этого ответа со многими улучшениями и сделал ее доступной в nuget: github.com/Nucs/JsonSettings
Есть еще один способ сохранить / загрузить настройки, использующие формат json, - это библиотека Config4Net, она также может отображать окно для редактирования этих настроек во время выполнения. Особенно, если вы хотите создать форму настроек, которая привязывается к определенному объекту настроек, поэтому с этой библиотекой остается всего одна строка, и все готово.
Не записывайте в ту же папку, что и ваш exe, если вы не работаете над приложением, которое, как вы знаете, будет установлено только в appdata. Если ваш exe установлен в любую из программных папок, то вряд ли пользователь сможет сохранять там файлы. Почему нет? Оказалось, что разрешение приложению сохранять файлы туда, где хранятся dll и exe, было лазейкой в безопасности.
Аргумент 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
Иногда вам нужно избавиться от этих настроек, хранящихся в традиционном файле web.config или app.config. Вам нужен более точный контроль над развертыванием записей настроек и разделенным дизайном данных. Или требуется включить добавление новых записей во время выполнения.
Могу представить два хороших варианта:
Преимущество строго типизированной версии - строго типизированные имена и значения настроек. Нет риска смешивания имен или типов данных. Недостатком является то, что нужно закодировать больше настроек, их нельзя добавить во время выполнения.
Преимущество объектно-ориентированной версии состоит в том, что новые настройки могут быть добавлены во время выполнения. Но у вас нет строго типизированных имен и значений. Будьте осторожны со строковыми идентификаторами. При получении значения необходимо знать тип данных, сохраненный ранее.
Вы можете найти код обеих полнофункциональных реализаций ЗДЕСЬ.
Другие варианты, вместо использования настраиваемого файла XML, мы можем использовать более удобный для пользователя формат файла: файл JSON или YAML.
Вы можете хранить свой файл настроек в нескольких специальных папках (для всех пользователей и для каждого пользователя), как указано здесь 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, но мне просто интересно, есть ли очевидный способ решения этой проблемы, поскольку этот подход, похоже, сработал для вас.
@PhilipStratford Поскольку это обычный файл, вы можете сохранить его где угодно. Просто найдите место с доступом для записи.
@PhilipStratford Может быть, папка AppData - это вариант для вас, см. C# получает путь к% AppData%, как упоминалось летающий змей.
Спасибо, я это уже реализовал, сохранив xml-файл в папке AppDate. Мне просто интересно, есть ли простой способ сохранить его в папке приложения в соответствии с вашим примером, поскольку я предполагал, что вы заставили его работать. Не волнуйтесь, папка AppData, вероятно, в любом случае лучше!
Я хотел поделиться библиотекой, которую я создал для этого. Это крошечная библиотека, но большое улучшение (ИМХО) по сравнению с файлами .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) - есть принципиальные отличия,здесь описано.
Оба предоставляют разные способы сохранения изменений:
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 - Пожалуйста, рад, что я смог вам помочь!
Хороший! Наконец-то во всем разобрался ???
Это приложение .NET WinForms? Если да, то на какой версии .NET вы работаете?