如何从一个项目引用另一个项目的应用程序设置?

9
在VB.Net项目中,您可以使用属性页面的“设置”选项卡来定义应用程序设置。在代码中引用设置时,您可以使用VB中的语法My.Settings.SettingName。
在设置选项卡上,您可以选择访问修饰符。它可能是“Friend”或“Public”。据推测,当您选择“Public”时,您正在使设置可供其他程序集访问。但是,一旦选择了“Public”,我就无法找出从另一个项目引用一个项目的设置的语法。实际上,使用“Internal”与使用“Public”作为访问修饰符之间没有任何区别。
我的问题是:选择“Public”作为访问修饰符是否会使设置对其他程序集可用?如果是这样,从其他程序集引用设置的语法是什么?如果不是,那么“Public”是什么作用?

我最初认为这个问题适用于VB和C#,所以我为两种语言都提出了问题。然而,我现在意识到我对C#是错误的 - 在那里没有关于语法的神秘(使用[Namespace] .Properties.Settings.Default.[SettingName])。然而,我仍然没有弄清楚VB的语法,因此我编辑了问题,只适用于VB,并继续寻找该语言的答案。 - T.C.
5个回答

6
你混淆了很多事情。设置没有可访问性修饰符,它们始终是公共的。然而,在Winforms应用程序中,确实有一个“应用程序设置”属性在控件的属性窗口中。就在顶部。还有一个修饰符属性。在VB.NET项目中默认为Friend,在C#应用程序中为Private。这决定了控件变量的可访问性,而不是设置。
是的,My.Settings允许您访问存储控件属性值的设置。但好消息到此为止。您应该始终将设置设计器中设置的范围设置为用户。这样,当程序重新启动时,可以保存和恢复该值。
具有用户作用域的设置存储在一个难以找到的文件中。这种文件的典型路径是C:\Users\hpassant\AppData\Local\WindowsFormsApplication1\WindowsFormsApplication1._Url_2acx4ldi2zmg42elj3eyqq0snhqco4qe\1.0.0.0
第一部分是我,我的笔记本电脑的当前用户。路径名的古怪部分是哈希,这是一个对于应用程序名称和版本是唯一的值。可能还有其他东西,比如我编译应用程序时的月相。计算该哈希的算法没有记录。只是它将是我应用程序的唯一标识,并且不能被另一个应用程序覆盖。
这就是问题所在,一个应用程序无法找到另一个应用程序的用户作用域设置。如果这对您很重要,您将不得不放弃使用设置,并将其替换为位于已知位置的XmlDocument。

1
Hans,感谢您的回复。我不太理解细节,但我认为我理解了结论——“一个应用程序无法找到另一个应用程序的用户作用域设置”。然而,这与此有关吗?我并不是要让一个应用程序读取另一个应用程序的设置;我正在尝试让一个项目读取(并写入)它引用的另一个项目的设置。 - T.C.
2
是的,我认为我的回答的任期与此相关。你不能编写另一个应用程序的设置,除非它们在一个你知道的可写位置。你知道它们保存在哪里吗? - Hans Passant

3
我正在寻找同样的东西,这是它:
在C#中:
   [Namespace]。属性设置。默认值。[SettingName]
在VB中:
   [Namespace]。我的。我的设置。默认值。[SettingName]

1
这个VB.NET版本对我来说不起作用,尽管我已经将其他项目的设置设置为“公共”。我想看到的是一个解决方案级别的设置对象;在项目之间传递数据库连接凭据非常麻烦。 - SteveCinq
更新:这确实有效,但仅当项目的命名空间不同时才有效。请参阅我的其他答案。(对于投票下降我表示歉意,但 SO 不允许我删除它!) - SteveCinq

0

我认为你可以在应用程序启动时将设置对象的实例从一个DLL传递到另一个DLL中,然后使用此类的Item属性访问设置(Setting类是从ApplicationSettingsBase继承的类)

'在DLL1中: Class1 Shared Property SettingsFromAnotherDLL As ApplicationSettingsBase ...

'在DLL2中:(在启动时完成) Class1.SettingsFromAnotherDLL = My.Settings.Default

'在DLL2中访问设置时 Dim Setting As STring = Class1.SettingsFromAnotherDLL.Item("SettingKey")


Mike,我尝试了和你提出的类似的东西。我创建了一个单例,有效地包装了Settings单例并使其公开。无论设置访问修饰符设置为“Friend”还是“Public”,都可以使用该方法。我希望一旦理解了“Public”的目的,它将导致更简单的解决方案。 - T.C.

0

以下是示例代码,用于获取位于我们执行应用程序附近的任何 .exe 的名为 DataBaseName 的设置值,并将其存储在“dbName”变量中:

string currentDirectory = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string exeName = System.IO.Path.GetFileName(Assembly.GetExecutingAssembly().Location);
FileInfo[] fileInfos = new DirectoryInfo(currentDirectory).GetFiles("*.exe");
foreach (FileInfo fi in fileInfos)
{
    if (fi.FullName == System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)) continue;

    Assembly asm = Assembly.LoadFrom(fi.FullName);
    Type[] allTypes = asm.GetTypes();
    foreach (Type type in allTypes)
    {
        if (type.Name != "Settings") continue;
        Type settingsType = type;

        PropertyInfo propDefault = type.GetProperty("Default");
        object defaultSettings = propDefault.GetValue(null, null);
        PropertyInfo piDBName = settingsType.GetProperty("DataBaseName");
        string dbName = (string)piDBName.GetValue(defaultSettings, null);

        break;
    }

    break;
}

0

在VB.NET中,这比C#略微棘手一些。这主要是因为在VB.NET中,命名空间不是如此关键。因此,在VB.NET解决方案中,对于所有项目/子程序集具有相同根(默认)命名空间并不罕见 - 尽管这可能不是很好的做法,例如:

MyNamespace.Main, MyNamespace.ClassLib1, MyNamespace.ClassLib2, MyNamespace.Common, etc.

由于这个原因,在问题的其他位置描述的项目间设置访问方法会失败。

在VB.NET中访问引用项目中的设置的建议方式是:

  1. Settings 访问修饰符设置为 Public
  2. 使用 {MyNamespace}.My.MySettings.Default.{MySetting} 访问设置(只读)。

请注意,My.MySettings 是直接属于 MyNamespace 的属性,而不是程序集名称的属性。

只有当子程序集的命名空间与引用项目的命名空间不同时,您才能访问 MySetting。如果命名空间相同,则根本不可见,我找不到任何访问它的方法。(我可以深入研究ILM,也许找出编译器为避免冲突所做的事情 - 这可能是否则的情况 - 但这是一个无关紧要的问题。)

我已经在C#.NET和VB.NET中进行了测试。尽可能区分您的根命名空间,你就会有喜悦。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接