2017-02-24 50 views
1

首先,我们的应用程序的一些背景:部署时,我们的应用程序将安装在Program Files目录中的客户端机器上。我们使用存储在程序附带的App.config文件中的连接字符串。在大多数情况下,这些连接字符串永远不会改变。但是,在某些情况下,连接字符串信息可能会过期。为此,我们在我们的程序中包含了一项功能,允许用户在无法访问数据库时输入新的数据库信息。信息被解析成连接字符串,经过有效性测试,并且如果有效,则写回到配置文件中。 (是的,此更改旨在影响计算机上的所有用户,因为无论如何,如果没有有效的连接字符串,它们将无法运行应用程序 - 如果一个用户知道数据库信息,则同一台计算机上的其他用户将受益从这些知识。写入App.config而不是每个用户的设置文件是首选。)如何让用户修改存储在app.config中的连接字符串,如果它们缺少写入权限?

我遇到的问题是,最终用户将不具有管理员权限,因此将无法运行我们的应用程序的级别允许它对自己的配置文件进行任何更改(因为它位于C:\ Program Files目录中)。我期待在两个不同的选择,但我在实施他们每个人的问题:

  1. 移动配置文件到不同的位置。在这种情况下不可能,因为我们正在部署一个可执行文件,并且据我所知,App.config文件必须驻留在同一个目录中。

  2. 将连接字符串信息分隔到外部配置文件中。我知道configSource属性可以添加到App.config的连接字符串部分。但是,我很难指定具体的目标。我不能简单地将文件放在可执行文件旁边(否则我会得到与常规App.config相同的权限问题)。但是,似乎不支持将环境变量(如%AppData%)作为有效的配置源。我试图实现this question的解决方案,但程序崩溃之前,我可以将配置源更改为有效的字符串,因为ConfigurationManager显然试图立即读取配置源文件夹,从而崩溃与FileNotFoundException。

  3. 创建我们自己的配置文件实现。我总是可以创建一个专用于读取位于特定位置的配置文件的自定义类,但如果可能的话,我宁愿使用内置的ConfigurationManager。

我的主要问题是:我怎样才能让最终用户(仅谁已经在应用程序文件夹的读取权限)来动态修改配置设置时,配置文件必须留在应用程序文件夹?

+0

好吧,如果客户没有给你obviosuly需要到别的地方保存设置,或给他们权限的文件系统写访问。例如,您可以将设置保存到远程数据库并从中读取,而不是从App.config中读取。在运行时将设置保存到App.config文件听起来像是一个坏主意。您也可以尝试使用Settings类保存设置:https://msdn.microsoft.com/en-us/library/a65txexh(v=vs.140).aspx。 – mm8

+0

你为什么如此结婚使用'ConfigurationManager'?如果你正在做非标准的事情,那么你也需要使用自定义方法。 – DavidG

+0

@DavidG我想使用ConfigurationManager,因为它已经在那里,并且确实(大部分)是我想要做的。它也是框架的一部分,所以我不需要重新测试它。如果我推出我自己的解决方案,我需要花时间测试和维护它,当已经有一个可以处理配置的内置类时,这似乎是多余的。 –

回答

0

由于Windows XP中,操作系统阻止具有管理员权限的程序写入Program Files文件夹。 “程序数据”文件夹创建为允许程序存储持久性信息。我总是使用自定义配置文件来存储最终用户需要配置以连接到数据库的程序数据。我还至少加密了连接字符串的密码,但这是另一个讨论。我提供了一个示例类和用法,用于在程序数据文件夹中存储配置文件。

配置类

using System; 
using System.IO; 
using System.Xml.Serialization; 

namespace MyNamespace 
{ 
    public class Config 
    { 

     public string SomeStringProperty { get; set; } 
     public int SomeIntProperty { get; set; } 

     private static string _filePath = null; 

     static Config() 
     { 
      _filePath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData) + @"\My Program Name"; 
     } 

     public static Config LoadConfig() 
     { 
      if (File.Exists(_filePath)) 
      { 
       try 
       { 
        XmlSerializer reader = new XmlSerializer(typeof(Config)); 
        StreamReader file = new StreamReader(_filePath); 
        Config config = (reader.Deserialize(file) as Config); 
        return config; 
       } 
       catch (Exception ex) 
       { 
        //Deal With no file file read error here. 
       } 
      } 

      // IF we get here no valid config file was loaded so make a new one. 
      return new Config(); 

     } 

     public Exception SaveConfig() 
     { 
      try 
      { 
       XmlSerializer writer = new XmlSerializer(typeof(Config)); 
       StreamWriter file = new StreamWriter(_filePath); 
       writer.Serialize(file, this); 
       file.Close(); 
       return null; 
      } 
      catch (Exception ex) 
      { 
       return ex; 
      } 
     } 
    } 
} 

基本用法

Config config = Config.LoadConfig(); 
Debug.WriteLine("SomeIntProperty=" + config.SomeIntProperty.ToString()); 
Debug.WriteLine("SomeStringProperty=" + config.SomeStringProperty); 

config.SomeIntProperty = 10; 
config.SomeStringProperty = "Hello"; 

config.SaveConfig(); 
相关问题