我在应用程序开始时运行以下方法,传入applicationSettings下的部分:
public static void EncryptConfigSection(string sectionKey)
{
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ConfigurationSection section = config.GetSection(sectionKey);
if (section != null)
{
if (!section.SectionInformation.IsProtected)
{
if (!section.ElementInformation.IsLocked)
{
section.SectionInformation.ProtectSection("RSAProtectedConfigurationProvider");
section.SectionInformation.ForceSave = true;
config.Save(ConfigurationSaveMode.Full);
ConfigurationManager.RefreshSection(sectionKey);
}
}
}
}
以下是app.config中的部分示例:
<applicationSettings>
<Example.Properties.Settings>
<setting name="Key" serializeAs="String">
<value>Value</value>
</setting>
</Example.Properties.Settings>
</applicationSettings>
当我尝试访问该部分中的任何设置时,收到以下错误:
无法识别的属性'configProtectionProvider'
这是一个桌面应用程序,需要在启动时加密某些设置,然后在退出时解密。
有没有人能解决这个问题?
答案 0 :(得分:5)
我发现了这个:http://andybrennan.wordpress.com/2014/06/05/unrecognized-attribute-configprotectionprovider-after-encrypting-app-config/。它解决了这个问题。
只需使用博客上写的这个方法:
private void ResetConfigMechanism()
{
typeof(ConfigurationManager)
.GetField("s_initState", BindingFlags.NonPublic |
BindingFlags.Static)
.SetValue(null, 0);
typeof(ConfigurationManager)
.GetField("s_configSystem", BindingFlags.NonPublic |
BindingFlags.Static)
.SetValue(null, null);
typeof(ConfigurationManager)
.Assembly.GetTypes()
.Where(x => x.FullName ==
"System.Configuration.ClientConfigPaths")
.First()
.GetField("s_current", BindingFlags.NonPublic |
BindingFlags.Static)
.SetValue(null, null);
}
保存/刷新配置后调用它。
答案 1 :(得分:3)
根据这篇博客文章,解决方法是在父级上调用RefreshSection()
:
RefreshSection("applicationSettings")
答案 2 :(得分:3)
我设法让Rick Schott的答案有效,但有一个重要的警告 - 你不能使用ConfigurationManager.GetSection的静态版本在刷新后检索该部分 - 你必须使用Configuration.GetSection。
完整代码:
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ConfigurationSection section = config.GetSection("passwordSection") as ConfigurationSection;
if (!section.SectionInformation.IsProtected)
{
// Encrypt the section.
section.SectionInformation.ProtectSection("DPAPIProtection");
section.SectionInformation.ForceSave = true;
config.Save(ConfigurationSaveMode.Modified);
// The passwords are now encrypted.
// Refresh the *parent* of the section that your passwords are in.
ConfigurationManager.RefreshSection("configuration");
// Now use Configuration.GetManager to retrieve the new password section.
// This doesn't throw the Configuration Exception :)
ConfigurationSection section2 = config.GetSection("passwordSection") as ConfigurationSection;
}
答案 3 :(得分:2)
我无法在应用程序运行时加密/解密配置文件并继续读取值。
虽然不是我想要的,但问题的解决方案是在应用程序运行之前首先加密/解密.config。
这是另一种方法,我没做但看起来很有趣: Encrypting Passwords in a .NET app.config File
答案 4 :(得分:0)
这篇文章刚刚保存了我的一天,以防有人需要在vb和2017中修复
Private Sub ResetConfigMechanism()
GetType(ConfigurationManager).GetField("s_initState", BindingFlags.NonPublic Or BindingFlags.Static).SetValue(Nothing, 0)
GetType(ConfigurationManager).GetField("s_configSystem", BindingFlags.NonPublic Or BindingFlags.Static).SetValue(Nothing, Nothing)
GetType(ConfigurationManager).Assembly.GetTypes().Where(Function(x) x.FullName = "System.Configuration.ClientConfigPaths").First().GetField("s_current", BindingFlags.NonPublic Or BindingFlags.Static).SetValue(Nothing, Nothing)
End Sub