【问题标题】:How do I write to a non-standard config file?如何写入非标准配置文件?
【发布时间】:2012-06-12 17:00:14
【问题描述】:

我有一个名为 middle.config 的文件,它与 exe 部署在同一目录中,但我需要更新此文件中的值。这意味着我必须转到 C:\Program Files (x86)\ 目录才能访问该文件。尽管它被命名为 .config 文件,但它并不遵循 .config 文件的通常架构。它看起来像这样:

<configuationSettings>     
  <middleSettings      
   groupName="XYZ"     
   forkName="SomeDbName"     
   dbServerName="123.123.123.123"     
   cnnTimeoutSeconds="30"     
   cmdDefaultTimeoutSeconds="30"     
   cmdMediumTimeoutSeconds="60"     
   cmdLongTimeoutSeconds="480"     
   />     
 <userKeys>     
   <Assemblies value="C:\assemblies\" />     
 </userKeys>     
 <friendlyDbName value="NiceData"/>     
</configuationSettings>     

我可以使用 Xml 读取和操作内容,但是当我尝试将文件保存回来时,会引发“无权限”错误。我无法重新定位文件。我被这个遗留架构卡住了,所以我不能像使用 ConfigurationManager.OpenExeConfiguration 的普通 .config 文件一样对待它。我无法在此架构上定义部分或组(无论如何我都无法)。我的所有用户都是本地计算机上的管理员。

如何在受保护目录中覆盖或删除和替换此文件(我对权限错误的假设)?如果做不到这一点,有没有办法通过 ConfigurationManager.OpenExeConfiguration 以某种方式访问​​此架构。

{编辑从这里开始}

在这个场景中有三个应用,AB和我的C。应用程序 A 不知道任何其他应用程序。它可以连接到很多很多数据库,并且它会删除一个文件“middle.config”,其中包含指向上一个应用程序 A 会话使用的最后一个数据库位置的指针信息。应用程序B,我们称之为导入/导出应用程序,只在最后一个应用程序A 数据库位置进行操作。应用程序 B 读取“middle.config”文件以获取数据库指针信息,然后针对该数据库执行控制台命令。它对数据库的选定部分执行批量转储或批量导入。

这就是我来构建应用程序 C 时的情况,该应用程序使用导入/导出应用程序 B 来获取数据块并将它们返回到数据库。因此,为了让应用程序 C 使用应用程序 B 针对任何数据库,应用程序 C 必须修改“middle.config”文件,以便应用程序 B 找到正确的数据库。应用程序 C 是新的,另外两个是旧的。我要么找到一种方法来完成这项工作,要么强制用户启动应用程序 A 并指向感兴趣的数据库,然后关闭应用程序 A。这很不方便。

{编辑到此结束}

【问题讨论】:

  • 如果这是一次性任务,请以提升的权限启动您的应用程序...
  • 您是否以管理员身份运行程序?

标签: c# configuration app-config configuration-files config


【解决方案1】:

不建议将数据文件写入程序文件目录,因为这需要提升权限。仅仅为了更新配置文件而授予程序提升的权限与Principal of Least Privilege 冲突,后者指出

计算环境的特定抽象层,每个 模块(例如进程、用户或程序,取决于 主题)必须只能访问信息和资源 其合法目的所必需的

仅仅为了更新配置文件而赋予进程提升的权限(可能允许它做许多有害的事情)不是“合法目的”。 MS 推荐的做法是在别处写入该类型的数据。

请考虑将配置文件存储在ApplicationData folder 的子文件夹中。

【讨论】:

  • 我同意这种意识形态,但在这件事上我别无选择。这是一个旧版应用程序,我需要修改此文件才能让我的应用程序正常工作。
  • @JimBoone:在这种情况下,您可以 a) 修改特定配置文件的权限(推荐......也许是一次性的“修复”程序,或者只是指示用户了解如何操作);或 b) 以提升的权限运行您的程序(不太理想)
【解决方案2】:

您对受保护目录的假设是正确的。 Program Files 有一个访问控制列表,它可以防止以标准用户身份运行的进程进行修改,在 Vista 上,甚至可以防止未运行提升的管理员进程进行修改。使用标准配置类访问文件无法解决这个问题。

如果您绝对不能移动文件(Eric J. 说安装后写入 Program Files 是一个坏主意是正确的),那么您可以embed a manifest in your config file-editing program which will try to force elevation with a UAC prompt at launch。当然,最好的解决方案包括 a) 使用标准配置模式和 b) 将用户数据保存在用户可写的位置,但有时由于遗留原因这是不可能的。

很遗憾,我不知道有什么方法可以说服 ConfigurationManager 读取非标准架构。

【讨论】:

  • 那么,如果应用程序具有提升的权限,它可以写入程序目录吗?
  • 是的。 Makubex 建议一个单独的特权组件只运行那些需要提升的部分是一个更好的解决方案,但需要一些关于如何处理进程间通信的设计考虑,并且最好只提示提升一次,而不是每次保存时。
【解决方案3】:

建议您的应用在 AppData 位置文件夹下为当前用户创建自己的位置,而不是写入应用安装位置下的文件(尤其是在非常严格的 Program Files 下)。不建议强制以管理员身份运行您的应用程序的用户。

【讨论】:

    【解决方案4】:

    将逻辑移动到一个单独的进程中,并使用当前应用程序的管理员权限启动它。

    【讨论】:

    • 多说一点概念。您的意思是在单独的进程中“隔离提升的权限”吗?
    • 是的。仅仅为此提升整个应用程序并不是一个好习惯。而是将管理此配置文件的部分移动到另一个控制台应用程序 - 这可以使用管理员权限执行。但请注意,它可能会向用户弹出 UAC dlg 框
    • 谢谢,我得先试一试。如果它有效,这将是答案。几周后我会知道(目前正在承诺交付)。
    【解决方案5】:

    换个角度看这个:Writing custom sections into app.config

    我发现链接的文章非常有用。但不确定它是否会回答你所有的问题。

    【讨论】:

      猜你喜欢
      • 2019-04-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-07
      • 2011-04-09
      相关资源
      最近更新 更多