关于在.NET Win应用程序中存储应用程序设置的位置的困惑

时间:2009-07-16 13:46:46

标签: .net connection-string appsettings

我需要知道应用程序设置(连接字符串)的存储位置和方式,以便在运行时更改它们并保存。

我知道在VS中您可以在Project> Properties下配置设置,这些设置存储在apps安装目录下的appname.exe.config文件中。但是“应用程序范围”在运行时不能读/写,如果你更改用户范围内的配置文件的副本将在用户目录下创建,并且不会被应用程序的其他用户访问。

我需要有一种方法,以便用户可以根据需要在应用程序内配置存储在公共配置文件中的连接字符串,然后让所有其他用户(在该计算机上)也可以使用它。我怎么能实现这个目标呢?

6 个答案:

答案 0 :(得分:9)

最简单,最快速的解决方案是在普通用户有权读/写的共享位置创建配置文件。

为您的配置数据创建一个包含公共属性的类,然后在此共享位置将其序列化为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);
    }
  }
}

答案 1 :(得分:5)

应用程序范围连接字符串是可写的,但您必须采用与获取字符串以供使用不同的方式。例如:

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

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

您还应该刷新该部分,以便正确检索更改。紧接着:

string sectionName = c.ConnectionStrings.SectionInformation.SectionName;
ConfigurationManager.RefreshSection(sectionName);

答案 2 :(得分:2)

正如其他人所指出的那样,您需要在计算机上创建一个可由应用程序的所有用户写入的共享位置。此位置可以是文件夹,文件或注册表。但是,Windows实际上有一个位置。您可以在MSDN上详细了解相关信息。您需要的文件夹是常用的应用程序数据:

  

CSIDL_COMMON_APPDATA

     

此文件夹应用于非用户特定的应用程序数据。例如,应用程序可以在CSIDL_COMMON_APPDATA文件夹中存储拼写检查字典,剪贴画数据库或日志文件。此信息不会漫游,并且可供使用该计算机的任何人使用。默认情况下,此位置对于普通(非管理员,非电源)用户是只读的。如果应用程序要求普通用户具有对CSIDL_COMMON_APPDATA的特定于应用程序的子目录的写访问权限,则应用程序必须在应用程序设置期间显式修改该子目录的安全性。修改后的安全性必须记录在供应商调查问卷中。

您可以通过调用

获取此文件夹的位置
Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);

在.NET应用程序中。在Vista上,此文件夹通常为C:\ProgramData

您必须在共享文件夹中创建自己的供应商和应用程序特定文件夹,这应该通过以提升的权限运行的安装程序来完成。此安装程序还应确保用户具有获取写访问权限所需的权限,如上面的引用所示。

答案 3 :(得分:1)

我这样做是因为我保存了一个XML文件,该文件是从具有SQL连接信息的POCO对象序列化到隔离存储中的。由于可以从那里读取和写入的用户帐户没有实际限制,因此您不必担心用户权限。

然后我修改了设置事件,以便在从应用程序设置文件中读取连接字符串属性时,我改为在隔离存储中反序列化XML文件,构建连接字符串,然后将其放入应用程序设置连接字符串属性。因为我在设置类本身内执行此操作,所以我能够写入它(但不能保存回文件)。

当我的应用程序运行时,如果它无法连接到服务器,我只需弹出一个窗口,询问sql服务器信息,然后输入并将其保存到隔离存储中,再也不要再问它了(即使通过升级)。

如果你有一个客户端应用程序(WPF或WinForms),其他机器上的用户将无法使用它,坦率地说,你可能找不到解决方案,除非你研究.Net Remoting或其他东西性质。但是,如果您在WinForms应用程序中的SAME计算机上有多个用户,则可以使用IsolatedStorage,它将适用于所有用户。

在settings类中,添加此事件处理程序:

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();
}

答案 4 :(得分:0)

读取和写入注册表曾经是建议的存储用户设置的方法,你仍然可以轻松地(使用Microsoft.Win32.Registry),但这种方法存在问题(主要是由于不同的权限级别)在您的用户中 - 某些用户不允许写入注册表的某些部分或创建新密钥。

答案 5 :(得分:0)

您的问题中存在一些相互矛盾的元素:

  

可以存储应用程序设置(连接字符串),以便在运行时更改它们并保存。

  

应用程序范围“在运行时不会读取/写入”,如果您更改用户范围下的那些,则会在用户目录下创建配置文件的副本,并且该应用程序的其他用户不会访问该文件。

最佳做法规定,要应用于系统的每个用户的设置(如连接字符串)应该可由系统的任何随机用户更改。这种设置只应由有资格管理系统的人员 进行更改。

因此,您描述的行为正是您的意图。如果你真的想让用户改变它,那就把它变成一个用户设置,这样如果用户搞砸了,他们只会为自己的帐户搞砸。