3

我正在.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");
4

2 回答 2

0

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

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

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

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

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

于 2012-10-30T08:59:43.080 回答
0

我尝试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),无需使用上述步骤。

于 2018-08-29T13:18:34.930 回答