【问题标题】:Exception Saving Configuration on Network Share in .NET 4.0.NET 4.0 中网络共享的异常保存配置
【发布时间】:2012-10-06 23:38:40
【问题描述】:

我正在 .NET 4 中创建一个应用程序,它需要在应用程序运行时更新应用程序的配置。执行此操作的代码如下:

Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.AppSettings.Settings["MySetting"].Value = "my value";
config.Save();

我的 App.Config 看起来像这样...

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="MySetting" value="my old value"/>
  </appSettings>
</configuration>

当我在本地驱动器上运行此应用程序时(因此,当程序运行时,配置文件也将位于本地驱动器上),则此代码有效。但是,如果应用程序使用网络共享(实际上是 Z:)上的配置文件运行,则代码将失败,并在 config.Save(); 行出现以下异常...

System.InvalidOperationException 未处理 消息=方法失败,出现意外错误代码 1。 源=mscorlib 堆栈跟踪: 在 System.Security.AccessControl.NativeObjectSecurity.CreateInternal(ResourceType resourceType,布尔 isContainer,字符串名称,SafeHandle 句柄,AccessControlSections includeSections,布尔 createByName,ExceptionFromErrorCode exceptionFromErrorCode,对象 exceptionContext) 在 System.Security.AccessControl.FileSystemSecurity..ctor(布尔 isContainer,字符串名称,AccessControlSections includeSections,布尔 isDirectory) 在 System.Security.AccessControl.FileSecurity..ctor(字符串文件名,AccessControlSections includeSections) 在 System.Configuration.Internal.WriteFileContext.DuplicateTemplateAttributes(字符串源,字符串目标) 在 System.Configuration.Internal.WriteFileContext.DuplicateFileAttributes(字符串源,字符串目标) 在 System.Configuration.Internal.WriteFileContext.Complete(字符串文件名,布尔成功) 在 System.Configuration.Internal.InternalConfigHost.StaticWriteCompleted(字符串流名称,布尔成功,对象 writeContext,布尔 assertPermissions) 在 System.Configuration.Internal.InternalConfigHost.System.Configuration.Internal.IInternalConfigHost.WriteCompleted(字符串流名称,布尔成功,对象 writeContext,布尔断言权限) 在 System.Configuration.Internal.InternalConfigHost.System.Configuration.Internal.IInternalConfigHost.WriteCompleted(字符串流名,布尔成功,对象 writeContext) 在 System.Configuration.Internal.DelegatingConfigHost.WriteCompleted(字符串流名,布尔成功,对象 writeContext) 在 System.Configuration.UpdateConfigHost.WriteCompleted(字符串流名称,布尔成功,对象 writeContext) 在 System.Configuration.MgmtConfigurationRecord.SaveAs(字符串文件名,ConfigurationSaveMode saveMode,布尔 forceUpdateAll) 在 System.Configuration.Configuration.SaveAsImpl(字符串文件名,ConfigurationSaveMode saveMode,布尔 forceSaveAll) 在 System.Configuration.Configuration.Save() 在 Z:\repos\project\MyProj\Program.cs:line 61 中的 MyProj.Program.Main() 在 System.AppDomain._nExecuteAssembly(RuntimeAssembly 程序集,字符串 [] 参数) 在 System.AppDomain.nExecuteAssembly(RuntimeAssembly 程序集,字符串 [] 参数) 在 System.Runtime.Hosting.ManifestRunner.Run(布尔 checkAptModel) 在 System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly() 在 System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext,字符串 [] activationCustomData) 在 System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext 激活上下文) 在 System.Activator.CreateInstance(ActivationContext 激活上下文) 在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone() 在 System.Threading.ThreadHelper.ThreadStart_Context(对象状态) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback 回调,对象状态,布尔 ignoreSyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback 回调,对象状态) 在 System.Threading.ThreadHelper.ThreadStart() 内部异常:

我认为这是 .NET 的某种安全问题,但我不确定如何禁用该安全性。

存储配置文件的网络共享实际上是一个 VirtualBox 共享驱动器。宿主系统为linux,共享驱动映射到Ext4文件系统。

我不认为这只是一个文件系统写入问题,因为我可以成功写入与我的 App.config 文件位于同一目录中的文本文件(至少我认为它是同一目录,除非 .NET 正在这样做幕后的一些时髦的东西,比如使用临时目录)。

File.WriteAllText("Text.txt", "Testing");

【问题讨论】:

  • 看起来像文件系统权限问题。运行程序的用户是否对共享有写权限?
  • @MarioDeSchaepmeester:我认为这不是问题。我能够使用相同的程序成功写入文本文件,没有任何问题。
  • VirtualBox 驱动器上的文件系统是什么?
  • @Richard:Virtualbox 主机正在运行 Linux,映射目录位于 Ext4 文件系统上。我不确定 Virtualbox 客户端 (Windows) 系统如何看待文件系统。
  • 可执行文件是否也在网络共享上?

标签: c# .net exception configuration


【解决方案1】:

这看起来像是代码访问安全问题,这里有一个很好的帖子:http://www.sellsbrothers.com/Posts/Details/1519

基本上,当您从网络驱动器运行应用程序时,默认情况下,它被赋予“Intranet”信任级别,我认为您不允许修改配置文件。

因此,基本上您需要通过执行以下操作来提升该驱动器的信任级别:

caspol -q -machine -addgroup 1 -url file://z:/* FullTrust -name "Z Drive"

希望对您有所帮助,我无法访问网络驱动器,因此无法确认。

【讨论】:

  • 这不适用于 .NET 4.0 - 从网络驱动器加载的所有内容都得到完全信任。这在 3.5 SP1 中已更改:blogs.msdn.com/b/brada/archive/2008/08/13/…
  • 正如理查德所说,您提到的问题不适用于 .NET 4.0。
【解决方案2】:

我尝试了caspol 并使用.Net 4 但没有成功。这可能很愚蠢,但我只是设法做到这一点:

  • 获取APP_CONFIG_FILE 并将其存储在局部变量中
  • 用本地文件系统中的文件替换实际的APP_CONFIG_FILE
  • 根据需要修改设置
  • 用本地的复制并覆盖网络驱动器上的APP_CONFIG_FILE
  • APP_CONFIG_FILE设置为网络上的原始文件
  • 删除本地文件

例如:

string APP_CONFIG_FILE = AppDomain.CurrentDomain.GetData("APP_CONFIG_FILE").ToString();
string TEMP_FILE = System.IO.Path.GetTempPath() + Guid.NewGuid();
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", TEMP_FILE);

Configuration config = 
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.AppSettings.Settings["MySetting"].Value = "my value";
config.Save();

File.Copy(TEMP_FILE, APP_CONFIG_FILE, true);
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", APP_CONFIG_FILE);
File.Delete(TEMP_FILE);

有趣的是,当我在安装了 Visual Studio 的机器上运行程序时,它运行良好(没有caspol),无需使用上述步骤。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多