Путаница в том, где хранить настройки приложения в приложениях .NET Win - PullRequest
2 голосов
/ 16 июля 2009

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

Я знаю, что в VS вы можете настроить параметры в Project> Properties, и они будут сохранены в файле appname.exe.config в каталоге установки приложений. измените их в пользовательской области, копия файла конфигурации будет создана в пользовательском каталоге и не будет доступна другим пользователям приложения.

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

Ответы [ 6 ]

9 голосов
/ 16 июля 2009

Самое простое и быстрое решение - создать файл конфигурации в общей папке, где обычные пользователи имеют права на чтение / запись.

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

public class Configuration
{
  // config filename
  private static _name = Path.Combine(
      System.Environment.GetFolderPath(
         Environment.SpecialFolder.CommonApplicationData),
      @"MyApp\MyConfig.xml");

  // the connection string
  public string ConnectionString {get;set;}

  // load the configuration from disk
  public static Configuration Load()
  {
    using (var f = File.OpenRead(name))
    {
      var x = new System.Xml.Serialization.XmlSerializer(typeof(Configuration));
      return x.Deserialize(f) as Configuration;
    }
  }

  // save the configuration to disk
  public static Save(Configuration config)
  {
    using (var f = File.OpenWrite(name))
    {
      var x = new System.Xml.Serialization.XmlSerializer(typeof(Configuration));
      x.Serialize(f, config);
    }
  }
}
5 голосов
/ 16 июля 2009

Строки подключения области приложения доступны для записи, но вы должны делать это иначе, чем получать строку для использования. Например:

Configuration c = ConfigurationManager
   .OpenExeConfiguration(ConfigurationUserLevel.None);

c.ConnectionStrings.ConnectionStrings["myConnectionString"]
   .ConnectionString = "theConnectionString";
c.Save();

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

string sectionName = c.ConnectionStrings.SectionInformation.SectionName;
ConfigurationManager.RefreshSection(sectionName);
2 голосов
/ 16 июля 2009

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

CSIDL_COMMON_APPDATA

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

Вы можете узнать местоположение этой папки, позвонив по номеру

Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);

в вашем приложении .NET. В Vista эта папка обычно C:\ProgramData.

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

1 голос
/ 16 июля 2009

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

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

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

Если у вас есть клиентское приложение (WPF или WinForms), пользователи на других машинах не смогут его использовать, и, откровенно говоря, вы, вероятно, не найдете решения для этого, если только вы не изучите .Net Remoting или что-то в этом роде. природа. Однако, если у вас на том же компьютере в приложении WinForms несколько пользователей, вы можете использовать IsolatedStorage, и он будет работать для всех пользователей.

В классе настроек добавьте этот обработчик событий:

VB:

Private Sub MySettings_SettingsLoaded(ByVal sender As Object, ByVal e As System.Configuration.SettingsLoadedEventArgs) Handles Me.SettingsLoaded   
  Me.Item("MyAppConnectionString") = MyLibrary.BuildConnectionString()   
End Sub 

C #:

protected override void OnSettingsLoaded(object sender, System.Configuration.SettingsLoadedEventArgs e)
{
  base.OnSettingsLoaded(sender, e);
  this["MyAppConnectionString"] = MyLibrary.BuildConnectionString();
}
0 голосов
/ 16 июля 2009

В вашем вопросе есть конфликтующие элементы:

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

.

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

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

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

0 голосов
/ 16 июля 2009

Чтение и запись в реестр раньше были рекомендуемым способом хранения пользовательских настроек, и вы все еще можете сделать это легко (используя Microsoft.Win32.Registry), но есть проблемы с этим подходом (в основном из-за различных уровней разрешений) среди ваших пользователей - некоторым пользователям запрещено писать в некоторые части реестра или создавать новые ключи).

...