【问题标题】:Accessing another project's settings file访问另一个项目的设置文件
【发布时间】:2011-02-02 15:47:15
【问题描述】:

有没有办法从不同的项目访问设置文件?例如,我有一个包含 2 个项目的解决方案(我们称它们为 Proj1 和 Proj2)。我想从 Proj1 中的 Program.cs 访问 Proj2 的应用程序设置。这可能吗?

【问题讨论】:

    标签: c# visual-studio-2005 application-settings


    【解决方案1】:

    选项 A:从其他程序集的配置文件(存储设置的位置)中解析值

    选项 B:在 Proj2 中创建一个公共类,将其设置中的必要值公开为静态属性,然后在 Proj1 中引用程序集并使用该类中的值。

    选项C:如果要公开所有设置,可以将设置类的访问权限从internal修改为public。

    我相信还有其他方法。

    【讨论】:

    • 我使用了选项 B,这也是我的第一个想法。谢谢!
    • 我尝试了选项 C,但似乎不起作用。我为每个项目提供了一组单独的设置:/
    【解决方案2】:

    如果您使用的是 C#,答案是:
    非常简单的答案是右键单击 proj2,选择设置选项卡。在顶部,您会发现设置类的访问修饰符是:internal,将其更改为 public。在 proj1 中添加对 proj2 的引用,以便查看 proj2 Settings 类。就是这样。

    【讨论】:

    • 好的,这绝对是有道理的,但是您应该如何在不编译的情况下更改这些设置?假设您使用项目 B 的引用设置部署项目 A。您想修改项目 B 的设置,但您所拥有的只是编译到 dll 中的默认值?这是我能找到的唯一解释,因为没有部署配置文件或与项目 A 的设置合并。
    • 我试过这个并且它有效,但它有@mikus所述的限制。此外,如果您使用 XML 转换(例如使用 SlowCheetah),Proj1 将不会看到转换的更改,即使重新编译也是如此。
    • 如果我可以投票两次,我会的,看看我是如何用谷歌搜索这个问题并找到这篇文章的......我显然已经投票了。
    • @Patrick 不要忘记在将类的修饰符更改为public 后构建proj2。
    • 谢谢!这可能不是所有人都忘记的,但您还需要将其他项目设置引用为“其他项目名称”。Properties.Settings.Default.“属性名称”
    【解决方案3】:

    我自己没有测试过这种方法,但 Eric De Carufel 的小技巧可能正是您所需要的:

    http://blog.decarufel.net/2007/10/getting-access-to-settings-in-another.html

    原来的链接似乎已失效,因为他已移至新博客并删除了旧内容。

    原文如下:

    在另一个项目中访问设置

    2007 年 10 月 25 日,星期四

    Visual Studio 2005 的新特性之一是新的属性编辑器。使用此属性编辑器,您可以轻松地将设置添加到您的应用程序。但是它的实施方式存在问题。让我解释一下为什么。

    通常这些设置特定于项目。当您在项目中添加设置时,与设置文件关联的特殊自定义工具会生成一个新类,您可以使用它来访问它。这个类的好处是它是强类型的。但在幕后,它只是从 xml 文件中获取密钥。这个生成的类被设置为“内部密封”。这可以防止从任何其他组件访问蜜蜂。如果您想集中编辑这些设置的位置怎么办。

    在多次尝试揭露它之后,我找到了一种快速简便的方法。假设我们的解决方案中有 2 个项目:一个引擎和一个 WinApp。每个都有设置,但我们希望它们可以从 WinApp 编辑。这是它的样子。

    如果您想在此处访问引擎设置,请使用以下技巧:添加链接文件。

    链接文件将作为 WinApp 项目的一部分进行编译。设置类仍然是内部的和密封的,但对于 WinApp 项目而不是引擎。

    这是最终结果:

    请注意,我添加了一个与我的引擎项目同名的文件夹。如果您想从许多项目中添加设置,这将很有帮助。

    有了这个,你可以从你的引擎类访问你的引擎设置,就像从你的 WinApp 类一样。你可以从你的引擎类中省略“引擎”部分,因为你应该在同一个命名空间中。它应该是这样的:

    namespace WinApp
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            public void AccessConfig()
            {
                Engine.Properties.Settings.Default.EngineSetting = "test";
            }
        }
    }
    

    【讨论】:

    • 链接已失效
    • 找到了链接复制到这里的原创内容(博客已经死了)
    【解决方案4】:

    除了这里已经给出的解决方案之外,我还必须想出另一个解决方案,因为我在包含设置的项目的 App.config 上使用 XML 转换(通过 SlowCheetah)。如果您不这样做,我推荐其他解决方案之一。

    我在消费项目(示例中的 Proj1)中添加了一个构建后步骤,以从 Proj2 的输出文件夹中复制配置文件。这将确保配置将应用转换。 (在我的例子中,Proj1 是一个 dll,所以如果你的是一个 exe,请将 DestinationFiles 从“.dll.config”更改为“.exe.config”。)来自 Proj1.csproj 的片段:

    <Target Name="AfterBuild">
      <Copy SourceFiles="..\Proj2\bin\$(Configuration)\Proj2.exe.config" DestinationFiles="$(TargetDir)\$(AssemblyName).dll.config" />
    </Target>
    

    然后,我通过 ctrl+shift+将文件拖到 Proj1,从 Proj2 创建了 Settings.settings 的链接(如 Kildareflare 引用的博客文章中所示)。

    然后我可以参考 Proj1 中的设置,类似于:Proj2.Properties.Settings.Default.MySetting。

    注意:如果您像我一样为单元测试执行此操作(Proj1 是一个测试 DLL),并且您正在使用 ReSharper 测试运行程序,请务必configure it to run tests in separate AppDomains。

    【讨论】:

      【解决方案5】:

      我将重新发布@Kildareflare 链接的内容以供将来参考。在 VS2015 中仍然有效,但对于我自己来说,我认为我更喜欢上面的“选项 B”。

      在另一个项目中访问设置

      Visual Studio 2005 的新特性之一是新的属性编辑器。使用此属性编辑器,您可以轻松地将设置添加到您的应用程序。但它的实现方式存在问题。让我解释一下原因。

      通常这些设置特定于项目。当您在项目中添加设置时,与设置文件关联的特殊自定义工具会生成一个新类,您可以使用它来访问它。这个类的好处是它是强类型的。但在幕后,它只是从 xml 文件中获取密钥。这个生成的类被设置为“内部密封”。这可以防止从任何其他程序集访问。如果您想集中编辑这些设置怎么办?

      在多次尝试揭露它之后,我找到了一种快速简便的方法。假设我们的解决方案中有 2 个项目:一个引擎和一个 WinApp。每个都有设置,但我们希望它们可以从 WinApp 编辑。这是它的样子。

      如果您想在此处访问引擎设置,诀窍是:添加链接文件。

      链接文件将作为 WinApp 项目的一部分进行编译。设置类仍然是内部的和密封的,但对于 WinApp 项目而不是引擎。

      这是最终结果:

      请注意,我添加了一个与我的引擎项目同名的文件夹。如果您想从多个项目中添加设置,这将很有帮助。

      有了这个,你可以从你的引擎类访问你的引擎设置,就像从你的 WinApp 类一样。你可以从你的引擎类中省略“引擎”部分,因为你应该在同一个命名空间中。它应该是这样的:

      namespace WinApp
      {
          public partial class Form1 : Form
          {
              public Form1()
              {
                  InitializeComponent();
              }
      
              public void AccessConfig()
              {
                  Engine.Properties.Settings.Default.EngineSetting = "test";
              }
          }
      }
      

      【讨论】:

      • 这对我不起作用。我仍然收到'Settings' is inaccessible due to its protection level
      【解决方案6】:

      由于Settings.Designer.cs 是internal 类,并且您不想弄乱生成的代码文件,我建议将辅助添加为“朋友”项目。

      发件人:C# "internal" access modifier when doing unit testing

      将以下代码添加到Proj2 的AssemblyInfo.cs

      using System.Runtime.CompilerServices;
      
      [assembly:InternalsVisibleTo("Proj1")]
      

      【讨论】:

        【解决方案7】:

        ConfigurationManager 涵盖了这些:

        string proj2Exe = @"C:\projects\proj2\bin\Debug\proj2.exe";
        Configuration proj2Config = ConfigurationManager.OpenExeConfiguration(proj2Exe);
        string mysetting = proj2Config .AppSettings.Settings["ThatSetting"].Value;
        

        【讨论】:

          【解决方案8】:

          今天遇到了这个麻烦,伙计。通过在第一个项目的app.config文件的configSections之间添加第二个项目的设置部分解决

          <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxxxx">
                <section name="fullSecondProjectName" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxxxx" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
          </sectionGroup>
          

          然后别忘了添加这些用户设置

          <configuration>
          
            <configSections>
              <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxxxx">
                <section name="fullSecondProjectName" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxxxx" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
              </sectionGroup>
            </configSections>
          
            ...
          
            <userSettings>
              <fullSecondProjectName>
                <setting name="LogMethodInvocation" serializeAs="String">
                  <value>True</value>
                </setting>
              </fullSecondProjectName>
            </userSettings>
          
          </configuration>
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2010-11-16
            • 1970-01-01
            • 2021-07-31
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-06-13
            相关资源
            最近更新 更多