简体   繁体   English

如果用户缺乏写入权限,如何允许用户修改存储在 app.config 中的连接字符串?

[英]How can I allow the user to modify connection strings stored in app.config if they lack write permissions?

First, some background on our app: When deployed, our application will be installed on a clients machine in the Program Files directory.首先,我们的应用程序的一些背景:部署后,我们的应用程序将安装在 Program Files 目录中的客户端计算机上。 We use connection strings which are stored in the App.config file that comes with the program.我们使用存储在程序附带的 App.config 文件中的连接字符串。 Under most circumstances, these connection strings will never change.在大多数情况下,这些连接字符串永远不会改变。 However, at some point, it may be possible that the connection string info will go out of date.但是,在某些时候,连接字符串信息可能会过时。 To that end, we have included a feature in our program that allows the user to enter new database information if the database can't be reached.为此,我们在程序中加入了一项功能,允许用户在无法访问数据库时输入新的数据库信息。 The information is parsed into a connection string, tested for validity, and written back into the config file if valid.信息被解析为连接字符串,测试有效性,如果有效则写回配置文件。 (Yes, this change is intended to affect all users on the computer, since they will be unable to run the application without a valid connection string anyway - if one user knows the DB info, then other users on the same computer will benefit from that knowledge. Writing to App.config instead of a per-user settings file is preferred.) (是的,这种变化旨在影响所有用户的计算机上,因为他们将无法仍要运行没有有效的连接字符串的应用程序-如果一个用户知道DB信息,然后其他用户在同一台计算机将受益于知识。最好写入 App.config 而不是每个用户的设置文件。)

The problem I'm running into is that the end user will not have admin permissions, and thus will not be able to run our app at a level that allows it to make any changes to its own config file (since it is located in the C:\\Program Files directory).我遇到的问题是最终用户将没有管理员权限,因此将无法在允许它对其自己的配置文件进行任何更改的级别上运行我们的应用程序(因为它位于C:\\Program Files 目录)。 I'm looking at a couple of different options, but I'm having problems implementing each of them:我正在研究几个不同的选项,但在实现每个选项时都遇到了问题:

  1. Move config file to a different location.将配置文件移动到其他位置。 Not possible in this case because we are deploying an executable, and from what I understand, the App.config file must reside in the same directory.在这种情况下不可能,因为我们正在部署一个可执行文件,据我所知,App.config 文件必须驻留在同一目录中。

  2. Separate the connection string info into an external config file.将连接字符串信息分离到外部配置文件中。 I know about the configSource property that can be added to the connection string section of App.config.我知道可以添加到 App.config 的连接字符串部分的configSource属性。 However, I'm having trouble specifying a concrete target.但是,我无法指定具体目标。 I can't simply put the file alongside the executable (otherwise I'd get the same permissions issues as the regular App.config).我不能简单地将文件放在可执行文件旁边(否则我会遇到与常规 App.config 相同的权限问题)。 However, it appears environment variables (such as %AppData% ) are not supported as valid config sources.但是,似乎环境变量(例如%AppData% )不被支持作为有效的配置源。 I have tried to implement the solution from this question , but the program crashes before I can change the config source to a valid string because the ConfigurationManager apparently attempts to read the config source folder immediately and thus crashes with a FileNotFoundException.我试图从这个问题实现解决方案,但程序在我可以将配置源更改为有效字符串之前崩溃,因为 ConfigurationManager 显然尝试立即读取配置源文件夹,因此因 FileNotFoundException 而崩溃。

  3. Create our own config file implementation.创建我们自己的配置文件实现。 I could always just create a custom class that is dedicated to reading a config file that is located in a specific location, but I would prefer using the built-in ConfigurationManager if possible.我总是可以创建一个专门用于读取位于特定位置的配置文件的自定义类,但如果可能,我更喜欢使用内置的 ConfigurationManager。

My main question is this: How can I allow the end user (who only has read permissions in the application folder) to modify config settings dynamically when the config file must stay in the application folder?我的主要问题是:当配置文件必须保留在应用程序文件夹中时,如何允许最终用户(仅在应用程序文件夹中具有读取权限)动态修改配置设置?

Since windows xp, the OS prevents programs with out admin privileges from writing to the Program Files folder.从 windows xp 开始,操作系统会阻止没有管理员权限的程序写入 Program Files 文件夹。 The "Program Data" folder was created to allow programs to store persistent information.创建“程序数据”文件夹是为了允许程序存储持久信息。 I always use a custom config file to store program data that an end User needs to config to connect to a database.我总是使用自定义配置文件来存储最终用户需要配置以连接到数据库的程序数据。 I also encrypt at least the password of the connection string, but that is a another discussion.我还至少加密了连接字符串的密码,但这是另一个讨论。 I provided a sample class and usage that stores a config file in Program Data Folder.我提供了一个示例类和用法,用于在程序数据文件夹中存储配置文件。

Config Class配置类

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

Basic Usage基本用法

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

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

config.SaveConfig();
var configuration = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");

var section = (ConnectionStringsSection)configuration.GetSection("connectionStrings");
section.ConnectionStrings["YourNameConnectionString"].ConnectionString = "yourstring";

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM