【发布时间】:2014-01-23 15:50:06
【问题描述】:
在我的 .NET 客户端应用程序中,我使用 Scope=User 和 Roaming=True 的默认设置提供程序。这在大多数环境中都可以正常工作,无论是客户端还是终端服务器,但拥有 Citrix 终端服务器场的客户除外。每当调用Properties. Settings.Default.Save() 时,都会抛出以下异常:
System.UnauthorizedAccessException: Attempted to perform an unauthorized operation.
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.FileSystemSecurity.Persist(String fullPath)
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.DelegatingConfigHost.WriteCompleted(String streamName, Boolean success, Object writeContext, Boolean assertPermissions)
at System.Configuration.ClientSettingsStore.ClientSettingsConfigurationHost.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.ClientSettingsStore.WriteSettings(String sectionName, Boolean isRoaming, IDictionary newSettings)
at System.Configuration.LocalFileSettingsProvider.SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection values)
at System.Configuration.SettingsBase.SaveCore()
at System.Configuration.SettingsBase.Save()
这个异常的原因:
-
System.Configuration.Internal.WriteFileContext在用户的漫游配置文件中写入用户设置的新副本 (...newcfg)。然后,DuplicateTemplateAttributes尝试修改此文件的 ACL,并将所有权显式设置为当前用户。 - 对于此客户,此操作失败,因为漫游配置文件存储在文件共享中,并且用户只有 读取 和 更改 权限,但没有 完全控制。他们可能在 NTFS 中具有完全控制权(因为默认情况下,您是您创建的所有文件的“所有者”,并且作为所有者,无论您是否明确设置了“完全控制”,您都可以对文件执行任何操作),但似乎就像它在 SMB 共享级别上被阻止一样。
这种行为对我来说没有任何意义:鉴于LocalFileSystemProvider 总是使用当前用户(本地或漫游)的私人配置文件文件夹,我们可以安全地假设用户反正是主人。
由于WriteFileContext 捕获异常,删除临时.newcfg 文件然后重新抛出,因此无法简单地在我的代码中捕获异常并重命名文件或以某种方式获取其内容,因为当抛出异常。
除了实现我自己的设置提供程序之外,我找不到解决此问题的任何简单方法。为此,我什至不得不重建序列化部分之类的东西,因为用于此的所有 System.Configuration 东西都是内部的。当然,我不想破坏当前使用的设置,所以它看起来像一个荒谬的代码量,只是为了重建所有内容,因为它只是“注释掉了一行”(设置文件的所有者)。
还有什么我可以尝试的想法吗?
客户无法更改其文件共享权限中的任何内容...
【问题讨论】:
-
备注:此应用面向 .NET 2/3.5 CLR。以 .NET 4.0/4.5 为目标会产生相同的异常,只是堆栈跟踪缺少几行,因此升级到较新的 .NET 版本无济于事。
-
@realMarkusScmidt 您能找到解决问题的方法吗?在我的情况下,它在正常的应用程序数据文件夹的情况下工作正常,但在应用程序数据文件夹的情况下出现问题,即重定向。我得到同样的异常。
标签: c# .net fileshare settings roaming-profile