I have implemented a winform application. I store the user settings for the application in the config file using the Configuration class.I store the exe along with the config file under the folder
C:\Users\\AppData\Local
This works fine in normal case, but I am facing problem in cases where user has redirected Appdata folder to some server address.In that case I get the exception:
Attempted to perform an unauthorized operation.
I found some similar questions here but none of them have any satisfactory answers.I tried to delete the config file before running the Configuration.Save command but that gives the exception:
The configuration file has been changed by another program.
So, how do I solve this problem. Here is my code to Update the config file:
string exePath = Path.Combine(Path.GetDirectoryName(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)), @"Local\<folder name>\<exe file name>");
Configuration configFile = ConfigurationManager.OpenExeConfiguration(exePath);
if (configFile.AppSettings.Settings[key] != null)
{
configFile.AppSettings.Settings.Remove(key);
}
if (param)
{
configFile.AppSettings.Settings.Add(key, value);
}
configFile.Save(ConfigurationSaveMode.Modified);
Here is the stack trace for the exception:
at System.Security.AccessControl.Win32.SetSecurityInfo(ResourceType
type, String name, SafeHandle handle, SecurityInfos securityInformation, SecurityIdentifier owner, SecurityIdentifier group, GenericAcl sacl, GenericAcl dacl)
at System.Security.AccessControl.NativeObjectSecurity.Persist(String
name, SafeHandle handle, AccessControlSections includeSections, Object
exceptionContext)
at System.Security.AccessControl.NativeObjectSecurity.Persist(String
name, AccessControlSections includeSections, Object exceptionContext)
at System.Security.AccessControl.NativeObjectSecurity.Persist(String
name, AccessControlSections includeSections)
at System.Security.AccessControl.FileSystemSecurity.Persist(String
fullPath)
at System.IO.File.SetAccessControl(String path, FileSecurity fileSecurity)
at System.Configuration.Internal.WriteFileContext.DuplicateTemplateAttributes(String source, String destination)
at System.Configuration.Internal.WriteFileContext.DuplicateFileAttributes(String source, String destination)
at System.Configuration.Internal.WriteFileContext.Complete(String
filename, Boolean success)
at System.Configuration.Internal.InternalConfigHost.StaticWriteCompleted(String
streamName, Boolean success, Object writeContext, Boolean assertPermissions) at System.Configuration.Internal.InternalConfigHost.System.Configuration.Internal.IInternalConfigHost.WriteCompleted(String streamName, Boolean success, Object writeContext, Boolean assertPermissions)
at System.Configuration.Internal.InternalConfigHost.System.Configuration.Internal.IInternalConfigHost.WriteCompleted(String streamName, Boolean success, Object writeContext)
at
System.Configuration.Internal.DelegatingConfigHost.WriteCompleted(String streamName, Boolean success, Object writeContext)
at System.Configuration.UpdateConfigHost.WriteCompleted(String
streamName, Boolean success, Object writeContext)
at System.Configuration.MgmtConfigurationRecord.SaveAs(String filename,
ConfigurationSaveMode saveMode, Boolean forceUpdateAll)
at System.Configuration.Configuration.SaveAsImpl(String filename, ConfigurationSaveMode saveMode, Boolean forceSaveAll)
at UtilityClasses.ConfigurationHandler.UpdateConfigFile(String key, String value, Boolean param)
I had a very similar expierience with changing a configuration file stored on a network share using
ConfigurationManager
.It truns out that the
Configuration.Save
initially creates a temp file in the same location with the desired access set to Write DAC (Write Directory Access Control).It even says so in the documentation:
The only workaround I could find in my environment was to copy the config to local directory, alter the file locally and then copy it back.