zoukankan      html  css  js  c++  java
  • C#配置文件加解密及多项目共享同一配置文件(转载)

            忙乎了一天,终于将VS 2005下应用程序配置文件加解密及多项目共用一个配置文件的问题搞定。

            实际要求是:因为准备编写一个数学试题库管理系统,自然考虑到要将数据库连接字符串保存到配置文件中,C#中当然是保存在App.Config文件。如果你的项目名称是TestLib,生成的可执行文件是TestLib.EXE,配置文件就是TestLib.EXE.Config。因为数据库连接的用户名和密码都是放在配置文件中,于是考虑到要将连接字符串加密。同时,为了方便部署,希望编写一个程序,能够按照要求修改连接字符串,并将其保存。这个程序要求必须是一个单独的EXE文件,仅在部署时才用到它。用户平时使用题库时并不需要用它。

           先解决数据库连接字符串加解密的问题。
           从“菩提树下的杨过.Net”的博客中找到了“再谈web.config/app.config敏感数据加/解密的二种方法”的文章(http://www.cnblogs.com/yjmyzz/archive/2008/08/22/1274395.html)

    加密的方法如下:
    //加密web.Config中的指定节
    private void ProtectSection(string sectionName)
    {
            Configuration config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
            ConfigurationSection section = config.GetSection(sectionName);
            if (section != null && !section.SectionInformation.IsProtected)
            {
                section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
                config.Save();
            }
    }
    //解密web.Config中的指定节
    private void UnProtectSection(string sectionName)
    {
            Configuration config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
            ConfigurationSection section = config.GetSection(sectionName);
            if (section != null && section.SectionInformation.IsProtected)
            {
                section.SectionInformation.UnprotectSection();
                config.Save();
            }
    }
    虽然是加解密ASP.NET中的Web.Config文件,但只要将
    Configuration config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
    改为:
    Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
    就可以了。
    加密前的配置文件为:
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <connectionStrings>
        <add name="MathConnStr" connectionString="Data Source=s10.0.13.100;Initial Catalog=Maths;User ID=Maths;password=5975238"
         providerName="System.Data.SqlClient" />
      </connectionStrings>
    </configuration>
    加密后的配置文件为:
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <connectionStrings configProtectionProvider="DataProtectionConfigurationProvider">
        <EncryptedData>
          <CipherData>
            <CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAnnUA3X3xO0G6yCdMO0YNYwQAAAACAAAAAAADZgAAqAAAABAAAAAhKw7WeiJ2xsjZ1uraDXgDAAAAAASAAACgAAAAEAAAAEKF+hGsklR2pcTePGmtB2igAQAAJDN2SLtXGNKojOGq9ukpFTJg0YrNlgEfaosx7Rxm9spCgKqolicr59L6mthOBeUaVxlx3Rk3YACr7IrWGDj6Pbu4macRf5V5TWSxUv+7dqyljS8uvUuEOLfC25Og4sYqyPsYk/dAnOFAFGbRhDGqlpsvGApOGzgb5vUorzqVVvvK38jdQU/klgqLcDJ5K+WC7GPTcuAfRrCcnvkHA2wPDb+XQGF9Y7ErmoQLazPlBOkIE6qyXQ/6xVEcIc/7FMX3KSgzxTGcITFHBxby/ZIFQ15uauHaxXR1v+gm22pG8o3lLZ1pw/7q5sBpR2wNdlNnl1ExB/t9PK6OFAITV2vOGL8tlx+Gl32+A3EsGGz7GKX3rdpKquugNuBytF3TYYl10k2Z1U/vLMgeUMhG0Ntdb4JJll4VbFmIS9AyBvxM5sO9ZbIbuYavH60BJ2Z1S+ZH1Hm37qjrq0yZLZUetf6RrvDKtkiJcmii6cX3pOt6Ecgdj2vitdN/OJva3JJDhAJOcC49lTwOH2ZZ29tfyuMB/8H/+avchr2e5MwLar2nZ3sUAAAAYczvUuIIqdw7NjlyFowywgYrxRQ=</CipherValue>
          </CipherData>
        </EncryptedData>
      </connectionStrings>
    </configuration>


            加解密数据库连接字符串很快就解决了,接下来要解决编写另外的小程序来修改这个连接字符串。开始考虑到直接做在试题库的应用程序中。
           从“我们的家园”博客上找到了修改数据库连接字符串(实际上可以是配置文件中的任何一节)的文章“读取并修改App.config文件(转载)”(http://www.cnblogs.com/xshy3412/archive/2007/11/24/971374.html),他也是转载的哟,从哪儿转载我就不知道了。这里面提供了一个修改数据库连接字符串的方法:
    ///<summary>
    ///依据连接串名字connectionName返回数据连接字符串
    ///</summary>
    ///<param name="connectionName"></param>
    ///<returns></returns>
    private static string GetConnectionStringsConfig(string connectionName)
    {
        string connectionString = 
            ConfigurationManager.ConnectionStrings[connectionName].ConnectionString.ToString();
        Console.WriteLine(connectionString);
        return connectionString;
    }

    ///<summary>
    ///更新连接字符串
    ///</summary>
    ///<param name="newName">连接字符串名称</param>
    ///<param name="newConString">连接字符串内容</param>
    ///<param name="newProviderName">数据提供程序名称</param>
    private static void UpdateConnectionStringsConfig(string newName,
        string newConString,
        string newProviderName)
    {
        bool isModified = false;    //记录该连接串是否已经存在
        //如果要更改的连接串已经存在
        if (ConfigurationManager.ConnectionStrings[newName] != null)
        {
            isModified = true;
        }
        //新建一个连接字符串实例
        ConnectionStringSettings mySettings = 
            new ConnectionStringSettings(newName, newConString, newProviderName);
        // 打开可执行的配置文件*.exe.config
        Configuration config = 
            ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        // 如果连接串已存在,首先删除它
        if (isModified)
        {
            config.ConnectionStrings.ConnectionStrings.Remove(newName);
        }
        // 将新的连接串添加到配置文件中.
        config.ConnectionStrings.ConnectionStrings.Add(mySettings);
        // 保存对配置文件所作的更改
        config.Save(ConfigurationSaveMode.Modified);
        // 强制重新载入配置文件的ConnectionStrings配置节
        ConfigurationManager.RefreshSection("ConnectionStrings");
    }
            有了这个,很快就实现了在应用程序中修改配置文件中已经加密的连接字符串。但考虑到将这个功能放在应用程序中,用户可能随便使用,于是考虑将其另外作为一个可执行文件,这样,用户就不会随便到可执行程序文件夹下执行这个程序了。
    联想到在一个解决方案中创建多个项目,并在主项目中添加对DbConfig项目的引用,DbConfig项目仍然作为Windows应用程序输出,可以在主程序输出目录中包含DbConfig项目的可执行文件。(作为类库项目只包含Dll文件)。
           但很快发现,DbCofnig.Exe文件只能读取和修改DbCofnig.Exe.Config文件的内容,你把他改成TestLib.Exe,是能读取TestLib.Exe.Config文件的内容。但主项目TestLib的可执行文件也是TestLib.Exe呀。不可取。

    怎么能做到多项目都能读取同一个Cofnig文件呢?考虑到ConfigurationManager.OpenExeConfiguration方法的另一个版本:
    ConfigurationManager.OpenExeConfiguration(string exePath),它可以指定具体哪个文件。结合Application.ExecutablePath可以获得可执行文件对应的Config文件。但仍然不行,DbConfig.Exe仍然只能读取DbConfig.Exe.Config文件。
    那就使用Application.StartupPath+@"\Db.config",只让它读取指定的Db.Config文件。
           调试了n遍,仍然是“未将对象引用设置到对象的实例”。

           郁闷ing...,再到网上去找!

           在“若我为上帝,谁为众生”的博客上,找到了这篇文章“再谈额外的配置文件读取和ConfigrationManager.OpenExeConfiguration(exePath)的误导性错误”(http://www.cnblogs.com/telephoner/archive/2008/07/15/1243260.html).
          晕!居然是微软的Bug。
    ----------------------------
    首先说ConfigrationManager.OpenExeConfiguration(exePath)的问题:
    1.此处是一个bug,exePath在msdn的说明中是要读取的配置文件的路径,而在生成System.Configuration.Configuration a = System.Configuration.ConfigurationManager.OpenExeConfiguration(exepath)的时候,实际在生成的a对象中,可以看到它的FilePath属性,让人大吃一惊,它显示的路径是原exePath路径+.config.
    所以a对象中永远为空,因为你的X.config是存在的,但它读取的却是X.config.config.

    这是否是我们的理解有误而非Bug呢?
    不,在试验在exePath中填写.config前面的部分后,提示错误,无法读取该配置文件,即它的ConfigurationManager.OpenExeConfiguration()方法要求exepath必须是一个.config文件!!!

    2.这个Bug可能的原因
    我猜想,它原来的读取的方法和类都是针对的配置文件的形式为:可执行文件文件名+.exe+.config的形式,或者是Machine.config.而这时不需要识别.config的,而当在.net 2.0里面时候,添加的这个读取额外配置文件的方法,由于一些失误,仍然是匹配的原来的老方法,导致它在读取是自动加上了.config.
    ---------------------------------------------------------------------------------------------
    解决方法
    我参考了<Configuration类在网页实现对web.config的修改>(http://tech.sina.com.cn/s/2008-06-30/1013712947.shtml)的方法
    即真假config文件的方法:
    1.先在项目的bin/debug目录下建立一个额外的config文件,即X.config;
    2.在同目录下建立一个X.config.config文件;
    3.所有信息都在X.config.config内,即appSettings节点等;
    4.然后读写都可以了.
    -----------------------------------------------------

           于是按照他所提供的方法来,在可执行文件的文件夹下同时存放Db.Config和Db.Config.Config,果然可以,并且将Db.Config文件必须要有,哪怕是个空的都中,删掉则不行。

          OK! 

     

    2008年12月15日晚22:00

  • 相关阅读:
    CSS3—— 2D转换 3D转换 过渡 动画
    CSS3——边框 圆角 背景 渐变 文本效果
    CSS3——表单 计数器 网页布局 应用实例
    CSS3——提示工具 图片廓 图像透明 图像拼接技术 媒体类型 属性选择器
    CSS3——对齐 组合选择符 伪类 伪元素 导航栏 下拉菜单
    CSS3——分组和嵌套 尺寸 display显示 position定位 overflow float浮动
    CSS3——盒子模型 border(边框) 轮廓(outline)属性 margin外边距 padding填充
    Eclipse连接数据库报错Local variable passwd defined in an enclosing scope must be final or effectively final
    数据库——单表查询
    数据库——添加,修改,删除
  • 原文地址:https://www.cnblogs.com/zhaobl/p/1421867.html
Copyright © 2011-2022 走看看