如何解决LocalFileSettingsProvider需要完全控制/ OwnerRights [英] How to work around LocalFileSettingsProvider requiring Full Control/OwnerRights

查看:270
本文介绍了如何解决LocalFileSettingsProvider需要完全控制/ OwnerRights的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的.NET客户端应用程序我使用默认设置提供与范围=用户和漫游= TRUE。这工作正常,在大多数环境中,如果没有客户端无论或终端服务器,但是用在Citrix终端服务器农场的客户。每当属性。 Settings.Default.Save()被调用时,以下异常被抛出:

In my .NET client application I use the default settings provider with Scope=User and Roaming=True. This works fine in most environments, no matter if client or Terminal Server, except for a customer with a Citrix Terminal Server farm. Whenever Properties. Settings.Default.Save() is called, the following exception is thrown:

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()

这样做的原因异常:

The reason for this exception:

  • System.Configuration.Internal.WriteFileContext 写的用户设置一个新的副本(<$ C C $> ... newcfg )在用户的漫游配置文件。然后, DuplicateTemplateAttributes 试图修改该文件的访问控制列表,并明确设置所有权为当前用户。
  • 在该客户失败的原因是漫游配置文件存储在一个文件共享和的情况下,用户只有修改的权限,但不是的完全控制的。他们可能在NTFS完全控制(因为默认情况下你是你创建的所有文件的老板,而作为业主,你可以,如果你有完全控制明确设置做任何的文件,不管),但似乎喜欢它挡在了SMB共享水平。
  • System.Configuration.Internal.WriteFileContext writes a new copy (...newcfg) of the user settings in the user's roaming profile. Then, DuplicateTemplateAttributes tries to modify the ACLs of this file and explicitly set the ownership to the current user.
  • In the case of this customer this fails because the roaming profile is stored on a file share and the users have only Read and Change permissions, but not Full Control. They probably have Full Control in NTFS (because by default you are "Owner" of all files you create, and as the owner, you can do anything with the file no matter if you have "Full Control" explicitly set), but it seems like its blocked on the SMB share level.

该行为没有任何意义,我:鉴于 LocalFileSystemProvider 总是的使用当前用户的专用配置文件的文件夹(本地或漫游),我们可以安全地假定用户是主人呢。

This behavior doesn't make any sense to me: Given that the LocalFileSystemProvider always uses a private profile folder of the current user (local or roaming), we can safely assume that the user is the owner anyway.

由于 WriteFileContext 捕捉异常,删除临时 .newcfg 文件,然后重新抛出异常,也没有办法只是在我的code捕获异常和重命名文件或以某种方式抓住它的内容,因为当异常被抛出它已经被删除了。

Since WriteFileContext catches the exception, deletes the temporary .newcfg file and then rethrows, there is no way to simply catch the exception in my code and rename the file or somehow grab its content since it is already deleted when the exception is thrown.

我找不到任何可以解决这个问题,除了实现自己的设置提供简单的方法。对于这一点,就好像我甚至会必须重建之类的序列化部分,因为所有使用这是内部的System.Configuration东西。当然,我不希望打破目前使用的设置,所以它看起来像code一个荒谬的数额只是为了重建一切,因为它是只一行注释掉(设置文件的所有者)

I couldn't find any simple way to work around this issue except for implementing my own settings provider. For this, it seems like I even would have to rebuild things like the serialization part since all the System.Configuration stuff used for this is internal. And of course I don't want to break the currently used settings, so it looks like a ridiculous amount of code just to rebuild everything as it is with just "one line commented out" (setting the owner of the file).

任何想法还有什么我可以尝试?

Any ideas what else I could try?

有没有办法在客户中的文件共享权限改变任何东西......

There is no way the customer changes anything in its file share permissions...

推荐答案

我也经历过在Citrix类似的问题 - 应用程序数据将被重定向到一个变化与放大器;读网络共享(而不是完全控制 - 它适用于完全控制)。在第一次运行时,我们的应用程序将创建的第一个保存()调用的user.config但抛出UnauthorizedAccessException在任何后续的保存()调用。

I have experienced a similar issue on Citrix - AppData is redirected to a "Change & Read" network share (not "Full Control" - it works on "Full Control"). On first run, our application will create the user.config on the first Save() call but throws UnauthorizedAccessException on any subsequent Save() calls.

答案似乎是,如果它调用保存()之前存在删除user.config文件

The answer appears to be to delete the user.config file if it exists before calling Save().

我们目前正在测试此与我们的客户 - 我会更新我的答案时,我有具体的结果。

We are currently testing this with our client - I will update my answer when I have concrete results.

更新::您需要亲密接触的每个设置在Settings.Default调用save()之前作为临时文件实际上是与现有的user.config合并。通过调用保存()之前调用下面的方法时,user.config正确地重新创建每次(无UnauthorizedAccessException抛出)。

Update: You need to "touch" each setting in Settings.Default before calling Save() as the temp file is actually merged with existing user.config. By calling the following method before calling Save(), the user.config is correctly recreated each time (no UnauthorizedAccessException thrown).

public static void ClearUserConfigFile()
{
    //Touch each setting
    foreach (SettingsProperty property in Settings.Default.Properties)
    {
        if (property.DefaultValue != Settings.Default[property.Name])
            Settings.Default[property.Name] = Settings.Default[property.Name];
    }

    //Delete the user.config file
    var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoaming);
    var userConfigPath = config.FilePath;
    try
    {
        if (File.Exists(userConfigPath) == true)
            File.Delete(userConfigPath);
    }
    catch (Exception ex)
    {
        _log.ErrorFormat("Exception thrown while deleting user.config : {0}", ex.ToString());
    }
}

这篇关于如何解决LocalFileSettingsProvider需要完全控制/ OwnerRights的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆